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 .
Related
As we all know AngularJS uses the simplest form of $watch when we bind to variable in template like this {{ $ctrl.obj }}.
It should compare value of $ctrl.obj by reference, but if I mutate $ctrl.obj the change is reflected in view. The reference doesn't changed, so why?
When we use brackets ({{}}) angular does not use any watch (ers) for detecting changes on the expression placed inside them. Instead this expression is dirty checked and refreshed in every $digest cycle, even if it is not necessary.
See this post: AngularJS : Why ng-bind is better than {{}} in angular?
I am learning angular js and have now a question where I couldn't find the right answer yet.
in the template HTML, you can use expressions to show the scope variables or call scope functions. But I see all the time different versions of it.
{{name}} shows the variable and binds it
{{::name}} the same thing but without binding
userdirective="{{::key}}" But what is the difference here?
ng-if="::field.sortable" With ng-if they are not using {{ but with there userdirective they do?
userdirective="{condition:isActive(route.name),mdColors:{color:'primary'}}" And then there is the last one with just one {. Thats when you create an object.right?
Maybe someone can help me to understand all of it.
Thank you very much for your time. Pat
{{name}} as you say is two-way data-binding
{{::name}} one way databinding
userdirective="{{::key}}" is the interesting case. This statement uses one-way binding into the userdirective ... which means after the $digest it just says userdirective="someValue"
So the userdirective gets that value as a plain value. Now I would have to test it but in the scopepart of the directiive it should say # so it gets read as a string and not as a expression.
The last one is simply as any JSON you build
{ name: value?true:false }
setting value according to conditions that angular evaluates, with a bit of magic involved :D
hope that helps
{{ anything here}} - That is angular expression interpolation. Angular interpolation - here you can find more about that. Basically idea that it interpolate anything you will put inside those brackets. So if you will put expression with some calculations or just variables related to current scope it will convert all variables to their values and apply calculations.
For instance: {{scopevar1 + scopevar2}} in case this variables has some values, let it be 1 and 2, as result we will see 3.
:: - This mean one time binding. For instance {{::scopevar1}} it will be interpolated once and will not check for changes of scopevar1, always stay as first value. Even if scopevar1 will change every second, the value in template will be the same. Angular Expressions - here you can find some live examples and more information.
userdirective="{{::key}}" - This case is nothing more then assigning dynamic value to your directive. UserDirective expectes to get a simple value, but we have it inside our scope, so we need to say: Hey, angular please interpolate scope variable - key, but only once, so my directive will get value, and will not looking for updates of key. And angular does it with pleasure!
userdirective="{condition:isActive(route.name),mdColors:{color:'primary'}}"
The last case is when your directive expects to get some kind of specific JSON. And we don't want to build it inside of controller. It is sometimes easier to do such things in the tempalte. So we put specific object with two properties: condition, mdColors. And saying that first property assigned to result of function, and second one is simple object {color:'primary'}.
That's it!
{{var}} is a two way binding expression and {{::var}} is a one-way binding expression. expression with :: will not change once set, it is a candidate for one-time binding.
go through : https://docs.angularjs.org/guide/expression for better examples on these
{{name}} is the regular case you will find. You basically print the variable name and update it once it changes.
{{::name}} is the same but your value will not receive updates once it stabilises.
So in the first case, your template updates once name is changed. In the latter, it isn't.
userdirective="{{::key}}" is a one-way one-time binding. Leave the :: out and your directive receives updates if key changes. However, if the directive changes key, it will not update the parent.
ng-if="::field.sortable" is a two-way binding. The changes go both ways. In this case, field.sortable is watched by the directive.
userdirective="{condition:isActive(route.name),mdColors:{color:'primary'}}" is used when you want to build adhoc-objects. A popular case is ng-class as well. You may build this object in the controller as well as you should not put too much logic in your template.
In any case, it is advisable to read the excellent docs https://docs.angularjs.org/guide
I have an ng-repeat and inside that ng-repeat i have
<p style="color:red">Booked Ref : {{agencyref(contentzz.Ref)}}</p>
With the way angular works it's constantly running the function, but that function has a HTTP request inside it, i just want to run it once. Is there something else i can use?
You're able to use the one-time binding syntax (::).
When using one-time binding the expression will only be evaluated once. After evaluation the watcher will be removed, thus the output of the expression will not be updated the next time the digest cycle is being triggered
Using one-time binding:
<p style="color:red">Booked Ref : {{::agencyref(contentzz.Ref)}}</p>
More info in docs: https://docs.angularjs.org/guide/expression#one-time-binding
If you wish to run this just once, why do you want to include it in ng-repeat?
Suggestion 1 : I suggest you can use ng-init in the parent tag and use the result later.
Suggestion 2 : You can make use of .run method of your angular module, however this is a very specific requirement. With your current question I am not sure if this will fit you or not, but this is another way of executing the method just once.
Use this
<p style="color:red" ng-if="$first">Booked Ref : {{agencyref(contentzz.Ref)}}</p>
So, this will get executed for the first element only.
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
Is there a built-in method to AngularJS to remove the automatically created watch on a value inserted into a template via curly braces.
For example:
<span>{{someVal}}</span>
In my case, someVal is never going to be changed after it's loaded the first time. I don't need the watch code listening for changes. I'm trying to speed up a page's performance that has a rather large table - some values the user can edit but most are read-only values.
I'm not setting up a watch manually so I don't have a reference to the deregistration method for each value. Do I need to write a custom directive to achieve this?
A buddy of mine found this set of directives for this exact purpose.
https://github.com/abourget/abourget-angular
I have recently found a better way of doing it as it's built in the angular:
<span>{{::someVal}}</span>
More information here: https://docs.angularjs.org/guide/expression