I've run into a problem where refreshing an AngularJS page in IE shows the uncompiled AngularJS. I can use ngCloak to hide the uncompiled expressions when loading, but I can't find anything for when the page unloads. I can use ngBind instead of an expression, and then the expressions disappear instead of displaying raw, but I'm hoping for a better solution. Any ideas?
I'm still working on a demo where you can see the issue; I think the iframes used to display results in code snippets and stuff like JSFiddle are preventing me from replicating the problem.
A few tips that may or may not help.
Contrary to common advice, load Angular in head of document. That way when you hit an ng-if during page load, the browser knows what to do with it. If it's in footer ng-if is meaningless until page is loaded and thus elements flash up and then disappear during page load
Use class .ng-cloak as you are doing already.
Use booleans in controller to dictate when to display elements. E.g.
<section ng-if='controller.loading === false'>
you could place some of or your entire markup for a view in such a div to remove elements until they are ready for display
Play with ng-if ng-show and ng-hide, ng-if actually removes elements from the DOM whereas the other two just show or hide. They can produce very different results in terms of smoothness of page loading.
Where you use an expressions on an ng-if, be careful to ensure the expression is very accurate. Don't be sloppy with the expression. Consider what would happen if the var in the expression was undefined. Would your element show when you don't want it to?
Whilst I haven't directly dealt with unloading these same concepts can be applied.
Related
It's normal that AngularJS creates a new ng-view every time a route is loaded, and then destroys the previous ng-view? It's just a fraction of time, but I can see both views on my app, and some directives which gather the element top also notice that behaviour (it seems that compilation is done before the original ng-view is removed from the DOM)
Has someone noticed this behaviour?
Yes, it's normal, this allows you to have transitions when the view gets replaced.
From the official documentation of ngView:
enter - animation is used to bring new content into the browser. leave
- animation is used to animate existing content away.
The enter and leave animation occur concurrently.
Actually ngView is not the only directive that behaves like that, for instance ngRepeat behaves exactly the same.
If you want to make sure that your views don't overlap, you could try this.
Add a class to the element of the ng-view so that you can easily target it from your css, something like this:
<div ng-view class="your-view"></div>
And then in your css do this:
.your-view.ng-leave { display:none; }
My problem is that when I use ng-cloak in pages that include elements which make use of directives with template code, ng-cloak does not wait for this template code to load and the page is shown incrementally and not as a whole (page elements first and after a while template code pops out).
I have tried to make a custom ng-cloak directive so that it won't remove element's ng-cloak class while any child element contains ng-cloak class but with no success. I thought this one would be a common issue, but I have not managed to find a solution online. Any help appreciated!
I don't think ngCloack was designed to cloak your content until everything is loaded. It is designed to prevent your content to be rendered in its raw form, what with expressions and all.
However, according to the documentation, it might work on the body element, but I haven't verified it myself:
The directive can be applied to the <body> element, but the preferred
usage is to apply multiple ngCloak directives to small portions of the
page to permit progressive rendering of the browser view.
I'm required to populate my bootstrap powered left navigation based on permissions stored in database.
Permission based menu data set will be fed from web api
So i tried to extend http://jsfiddle.net/kmussel/evXFZ/ directives to change my static menu to dynamic menu .
Everything goes well except collapse functionality is not working as expressions for dynamic ids for data-target is not evaluated somehow.
I have created http://jsfiddle.net/jaimini/gKnJ2/1/ ti mimic the issue I'm facing.
data-target="{{node.id}}"
is not evaluated and hence expand/collapse is not working.
I have also added hardcoded IDs in 2nd menu to show that my approach will work if the expression is evaluated as required.
Manage to solve the issue by removing target attribute from parent link.
updated the fiddle and now its working as per my need.
please note that for proper functioning of bootstrap collapse plugin
data-target="{{\'#navigation\'+node.id}}"
would be required.
This jsfiddle is like yours, it use recursive ng-repeat. The googgle discussion about rendering tree like structure is here.
The different between ng-if ng-switch to ng-show ng-hide is, ng-if will not render the html
if the condition not met rather than render those elements that is hidden but taking up
resources. It is not evident for menus because there are not alot of binding/watches use. But
imagine you have render 5 - 6 tabs with lots of form data.
I have an angular multi-step form in a modal window. It has a few different views and works great but at the end of it I just want to display a tiny snippet of HTML along the lines of 'Thank you, we will be in touch shortly'
However, I thought about creating a view for this with a partial but it seems incredibly over-engineered for what it is. Is there any way in angular of just replacing the view with that sentence without creating a whole new view? This will be called from a function in the final controller
Use ng-show and ng-hide to do this in your view. Suppose if your view is no longer needed you can hide it and show the Thank you snippet at its place by using ng-show.
ng-switch is what you are looking for.
From the docs:
"The directive itself works similar to ngInclude, however, instead of
downloading template code (or loading it from the template cache),
ngSwitch simply choses one of the nested elements and makes it visible
based on which element matches the value obtained from the evaluated
expression."
http://docs.angularjs.org/api/ng.directive:ngSwitch
you can this code, if you have one area of content
<ng-view></ng-view>
good method you can find in LINK
Recently migrated to 1.2.0-rc1 and really happy with it. Especially for the ngIf which can be a big performance improvement for rendering, compared to ngShow.
Except there is some flickering when the boolean changes. See the plunkr below for an example:
http://plnkr.co/edit/iYMm0IHZkrRamlaEs9yD?p=preview
On Chrome (v28), you'll see that the first 2 implementations will flicker whereas the 2 others won't.
On Firefox, the flicker happens only rarely.
Is that normal? Is there a way to avoid that? Should I go back to using ngShow?
Edit:
As sza said, ngIf and ngSwitch modify the DOM, whereas ngShow uses a css rule to display/hide elements. In angular 1.0.7, ngSwitch existed already and was already modifying the DOM and was great as we used it a lot in place of ngShow to avoid expensive rendering of things that were not displayed.
Now if you look at http://plnkr.co/edit/pIpEYZ5K8xvfd9dhAC74?p=preview, you'll see that there is no flickering with ngSwitch from 1.0.7.
The answer I'm expecting would be something like "this is normal behaviour, you're using ngSwitch and ngIf where they shouldn't be used, only static content should be displayed with ngSwitch and ngIf" or "this is a rendering bug, live with it until it is fixed". Of course a workaround would be nice too (#timp, I've seen your answer but I'm afraid I'd need a working example).
I asked the same question on the google group, and the answer was that it is a bug in the animation module:
https://groups.google.com/d/msg/angular/Fy-rVdXh5WQ/aqhppEl8Nw0J
Removing the dependency on the animation module will fix the flicker.
If you look into the source code, you will see both ngIf and ngSwitch are all related to DOM manipulation, while ngShowHide only manipulates the CSS rather than DOM.
I guess the DOM manipulation will be a slightly more expensive than CSS change in terms of reflow and it may differ in different browsers.
If you try the ngIf demo on the AngularJS documentation page (link), it has the same issue you described when the checkbox is toggled quickly.
If the improvement in rendering is important, try replacing the checked with two booleans. This way you can specify the order of which ngIf is evaluated first. It's a pain but it does the job.