Reputation: 20890
I've got a 400kb picture in a data url in my scope. I'm using <img ng-src='{{dataUrl}}'/>
, which is working, but extremely slowly: I assume angular is checking this 400kb value against itself every single frame. The angularjs batarang confirms that 95% of my total run time is spent $watching {{dataUrl}}
.
The dataUrl CAN change dynamically, but certainly not every frame - only when the user selects a new image.
How can I blast a new dataUrl into the DOM on events without using the full two-way binding features that are becoming so expensive?
Upvotes: 0
Views: 4613
Reputation: 89
You can use one-way-databiding, like this
<img ng-scr="{{::dataUrl}}"/>
Or if you are using an angular version bigger than 1.3 there is an one bind embedded. That you can use on almost any directive. The $digest list will handled the watches only once, after loaded they will be destroyed.
Upvotes: 1
Reputation: 752
The $watch function returns a callback just for that. You just have to execute it back to destruct the watcher.
var watcher = $scope.$watch('data', function(newValue, oldValue) {
if (newValue) {//you could do a isset here
watcher();
}
});
To re-watch. Might be expensive depending on the number of items on the current $scope
if(!$scope.$$phase) {
$scope.$digest()
}
Upvotes: 2
Reputation: 6187
You can use bindonce - a high performance one time binding for AngularJS that can render your results in 0 watches.
Example:
<ul>
<li bindonce ng-repeat="person in Persons">
<a bo-href="'#/people/' + person.id"><img bo-src="person.imageUrl"></a>
<a bo-href="'#/people/' + person.id" bo-text="person.name"></a>
<p bo-class="{'cycled':person.generated}" bo-html="person.description"></p>
</li></ul>
or:
<div bindonce="Person" bo-title="Person.title">
<span bo-text="Person.firstname"></span>
<span bo-text="Person.lastname"></span>
<img bo-src="Person.picture" bo-alt="Person.title">
<p bo-class="{'fancy':Person.isNice}" bo-html="Person.story"></p>
Update:
another One time binding for AngularJS as suggested by Ilan Frumer
Example:
<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>
Upvotes: 2