Render value without data-binding
JavascriptAngularjsData BindingJavascript Problem Overview
In AngularJS, how can I render a value without 2-way data binding? One may want to do this for performance reasons, or even rendering a value at a given point in time.
The following examples both use data binding:
<div>{{value}}</div>
<div data-ng-bind="value"></div>
How do I render value
without any data binding?
Javascript Solutions
Solution 1 - Javascript
Angular 1.3+
In 1.3, Angular has supported this using the following syntax.
<div>{{::message}}</div>
As mentioned in this answer.
Angular 1.2 and below
This is simple and doesn't need a plugin. Check this out.
This small directive will easily accomplish what you are trying to achieve
app.directive('bindOnce', function() {
return {
scope: true,
link: function( $scope ) {
setTimeout(function() {
$scope.$destroy();
}, 0);
}
}
});
You can bind once like this
<div bind-once>I bind once - {{message}}</div>
You can bind like normal
<div ng-bind="message" bind-once></div>
Demo: http://jsfiddle.net/fffnb/
Some of you may be using angular batarang, and as mentioned in the comments if you use this directive the element still shows as binding when it is not, I am pretty sure this has something to do with the classes that are attached to the element so try this, it should work (not tested). Let me know in the comments if it worked for you.
app.directive('bindOnce', function() {
return {
scope: true,
link: function( $scope, $element ) {
setTimeout(function() {
$scope.$destroy();
$element.removeClass('ng-binding ng-scope');
}, 0);
}
}
});
@x0b: If you have OCD and you want to remove the empty class
attribute do this
!$element.attr('class') && $element.removeAttr('class')
Solution 2 - Javascript
It looks like Angular 1.3 (starting with beta 10) has one-time binding built in:
https://docs.angularjs.org/guide/expression#one-time-binding
> One-time binding > > An expression that starts with :: is considered a one-time expression. > One-time expressions will stop recalculating once they are stable, > which happens after the first digest if the expression result is a > non-undefined value (see value stabilization algorithm below).
Solution 3 - Javascript
Use the bindonce module. You'll need to include the JS file and add it as a dependency to your app module:
var myApp = angular.module("myApp", ['pasvaz.bindonce']);
This library allows you to render items that are bound only once — when they are first initialized. Any further updates to those values will be ignored. It's a great way to reduce the number of watches on the page for things that won't change after they are rendered.
Usage example:
<div bo-text="value"></div>
When used like this, the property under value
will be set once it is available, but then the watch will be disabled.
Solution 4 - Javascript
Comparison between @OverZealous and @Connor answers :
With the traditional ngRepeat of angular : 15s for 2000 rows and 420mo of RAM (Plunker)
With ngRepeat and the module of @OverZealous : 7s for 2000 rows and 240mo of RAM(Plunker)
With ngRepeat and the directive of @Connor : 8s for 2000 rows and 500mo of RAM (Plunker)
I made my tests with Google Chrome 32.
Solution 5 - Javascript
As an alternative, there is angular-once
package:
> If you use AngularJS, have performance issues and need to display lots > of readonly data, this project is for you!
angular-once
was actually inspired by bindonce
and provides similar once-*
attributes:
<ul>
<li ng-repeat="user in users">
<a once-href="user.profileUrl" once-text="user.name"></a>
<a once-href="user.profileUrl"><img once-src="user.avatarUrl"></a>
<div once-class="{'formatted': user.description}" once-bind="user.description"></div>
</li>
</ul>