Angular Watchers Count for multiple ng-if with same variable - angularjs

Adding multiple time ng-if with same variable will cost more watcher?
I mean will it be a performance issue if I use as follows?
<span ng-if="contentLoaded">{{::MY_CONTENT_1}}</span>
<span ng-if="contentLoaded">{{::MY_CONTENT_2}}</span>
Or is there any good approach to handle it?

EDIT
It seems that #Jon Quarfoth is right :
"Unless there's some kind of smart deduping going on under the covers that I don't know about, I'm pretty sure that each ng-if creates a watch.
A quick look at the source shows a $scope.$watch being created in the ngIf directive's link function:
http://github.com/angular/angular.js/blob/master/src/ng/directive/…"

Related

When I don't need an ngCloak directive

Is there any case when I don't need an ngCloak directive?
It seems that every tag that somehow uses Angular library needs to define this directive either via ng-cloak attribute or class="ng-cloak".
Is there any downside of using this directive for every possible element?
ng-cloak will cause your element not to render straight away. Often elements will look fine without ng-cloak, in which case it would be strange to opt for a blank space.
This will often be the case if you are not using the {{x}} syntax. Perhaps you could use ng-bind instead.
Lots of elements will not be in the DOM at page load. For example, the template of a directive will obviously not be available until after the digest cycle has already run. It would be strange to try to cloak something which was not visible in the first place.
Using ng-cloak more than you need to will just hurt performance.

AngularJs alternative to ng-if to save digest

I recently started studying about digest and performance improvements in AngulaJs and found on my website that I'm using tons of ng-if.
Sometimes in ng-if there is a variable that may change, but often is fixed at the startup of the controller and then never changes.
What should I do so to improve performance avoiding digest to evaluate every loop those unchangeable ng-if? Should I change directive? With what?
E.g
In my header template I have a div that can be seen only by particular type of user. It's just a div, so I don't want to call some different template.
I put <div ng-if="userIsSuperior()"> ... </div>
When first evaluated, the return vale of userIsSuperior() never changes (during this session of course), but I know that AngularJs Digest evaluates it every loop.
How can I avoid this? Or am I missing something?
I think what you are looking for is one-time binding.
If you use:
<div ng-if="::userIsSuperior()"> ... </div>
Then the value of userIsSuperior() will only be calculated once and will stick to that value.
See demo.
First answer solutions needs AngularJS > 2.
I found a valid solutions in using OnceJS, library for one-time-binding.
Here

Angular to use ng-bind or {{}}?

Ok so I have read in several places that using ng-bind is better for performance.
But looking at these jsperfs makes me a bit confused :)
https://jsperf.com/angular-bind-vs-brackets
http://jsperf.com/ng-bind-vs-brackets/14
So what is the best way when it comes to performance?
{{::value}}
or
<div ng-bind="value"></div>
You should use ng-bind. Its a directive that puts a watcher on that variable so it only updates when the variable changes, while {{}} will dirty-check and refreshes the variable in every digest cycle.
See this answer
Also :: is called "bindonce" and will only set the variable once and wont update afterwards.
e: The jsperf tests binding from variable to html (I think), while the linked answer focuses on the behaviour afterwards. If you got 100 curly braces and you update one model, every {{}} gets updated. While ng-bind only updates if the variable itself changes, because it creates a watcher for that variable.
When it comes to one-time-binding, then you should also use the colon in ng-bind as well.
So use ng-bind="::value"
for filter or expressions you have to use brackets: ng-bind="::(value | number:2)"
use ng-bind is better . If javascript files is not loaded , {{ }} will show on the page .

Dynamically creating an ng-switch inside a directive

I'm trying to create a new directive that selects among several children using an ng-switch. This example is not much more than creating an ng-switch inside a directive, but eventually the directive will have more display sugar and some automatic functions so it seemed that creating a directive was the right solution.
My progress so far is in this plunker:
http://plnkr.co/edit/yeCiIOCQswYJHyTozQUZ
The $compile I'm doing seems to be evaluating the switch, and determining that the value doesn't match any of the when clauses which shouldn't be true. You can see that by inspecting the elements in the rendered picker.
I'm also concerned that calling $compile at this stage seems to have thrown away the item list, so it seems like I'm barking up the wrong tree.
How do I get the transcluded content to re-evaluate within the current state?
Update
I think I was barking up the wrong tree. Mathew's answer got me started in the right direction, so it was a big help.
As far as I can tell trying to construct a directive (ng-switch) inside a directive is a bad idea. In the previous plunker when the compile happened the template was changed permanently. That means if I changed the which parameter it wouldn't update. That's what was smelling funny to me in the first place.
Here is a revised plunker:
http://plnkr.co/edit/WUVgdXjwedxO4356321s
In this case, there's a watch on the 'which' value that refires the transclusion. That function removes the previous entry (if any) and adds the new one. There's a couple added benefits.
First I removed the 'item' directive. There's no reason for it to exist, since I'm just looking at the class. Second, I used $animator to do the list manipulation. That means you can add ng-animate to the picker and get animation effects.
I hope that helps someone else looking at this question.
There were two problems with your code:
1) Your template had which being evaluated so your on was becoming the number 1, instead of the variable you wanted which is "which":
template: '<div><div ng-switch on="which"></div></div>',
2) When you used compile, you needed to pass in the $scope like so:
$compile(sel)($scope);
Here's an updated plnkr for you: http://plnkr.co/edit/Q6ViJBvkLwQRgUKYMfS9?p=preview

ngIf and ngSwitch AngularJS

What's practical difference between ngIf and ngSwitch? Both directives manipulate the DOM, but ngSwitch is more verbose. Is the typical case to just use ngIf unless you need something really big in which case use ngSwitch?
Is there a situation where ngSwitch and ngIf are not direct replacements? Or is their only practical difference the syntax?
ngIf is basically a version of ngSwitch with a single condition. It's different from ngShow in that it removes the actual DOM element rather than simply hiding it. If you're using an ngSwitch with just a singly truthy condition check, then I believe ngIf will do the same thing.
Michele Tilley's got it exactly right, I believe, particularly in pointing out the contrast with ngShow/ngHide. There's one additional difference to note: ng-If will detach and re-attach an element in-place. But ng-Switch has an outer containing element on which you declare the main directive and its condition: ng-switch="expression". The conditional content within that outer element will be append()-ed as the last child of the outer element, thus changing its position relative to any non-conditional content within the outer element.
And, see this CodePen for an interactive demo of all three, showing the differences in execution.
EDIT: This behavior changed in Angular 1.2. Elements are now left in place. The Codepen above mentions and demonstrates this, providing a link to a 1.08 Plunk that has sadly been wiped out...
One more difference would be that ngIf and ngSwitch create new scopes, while ngShow/ngHide don't.
You can think in ngIf/ngSwitch in the same way you do with if/switch when you are coding. Obviously they do almost the same thing, but there are cases that a ngIf is better and there are cases where nfSwitch is better.

Resources