Reputation: 1022
I'm using angularjs and need to find the watch of the ng-repeat
, because I need ng-repeat
to stop working from a specific point. this my code:
<ul>
<li ng-repeat="item in items">
<div>{{item.name}}</div>
</li>
</ul>
I need to find the watcher of the ng-repeat
. If I go to scope.$parent.$$watchers[x]
and perform splice
the watch is removed, but how can I find the specific watch?
Upvotes: 2
Views: 5161
Reputation: 340
It's not possible to find the watch (see explanation below), but you can achieve what you wish by use the following directive
app.directive('repeatStatic',
function factory() {
var directiveDefinitionObject = {
restrict : 'A',
scope : true, // this isolates the scope from the parent
priority : 1001, // ng-repeat has 1000
compile : function compile() {
return {
pre : function preLink(tElement, tAttrs) {
},
post : function postLink(scope, iElement, iAttrs, controller,
transcludeFn) {
scope.$apply(); // make the $watcher work at least once
scope.$$watchers = null; // remove the $watchers
},
};
}
};
return directiveDefinitionObject;
}
);
and its usage is
<ul>
<li repeat-static ng-repeat="item in items">
{{ item }}
</li>
</ul>
See http://plnkr.co/k9BTSk as a working example.
The rational behind is that the angular directive ng-repeat directive uses internal function $watchCollection to add a self created listener that watchs the items object. Since the listener is a function created during the process, and is not keep anywhere as reference, there is no good way to correctly identify which function to remove from the $$watchers list.
However a new scope can be forced into the ng-repeat by using an attribute directive, in this way the $$watchers added by ng-repeat are isolated from the parent scope. Thus, we obtain full control of the scope.$$watchers. Immediate after the ng-repeat uses the function that fills the value, the $$watchers are safe to be removed. This solution uses hassassin's idea of cleaning the $$watchers list.
Upvotes: 5
Reputation: 5054
The way that I have dealt with this in the past is that I created a custom directive that copies the logic of the built in ngRepeat
directive but never sets up the watches. You can see an example of this here, which was created from the ngRepeat
code from version 1.1.5.
The other way, as you mentioned was to remove it from $$watchers
of a scope, which is a little stranger since it accesses a private variable.
How this could be done is that you create a custom directive on the repeat to remove the watch that is the repeat. I created a fiddle that does this. It basically just on the last element of the repeat clears the parent watch (which is the one on data)
if (scope.$last) {
// Parent should only be the ng-repeat parent with the main watch
scope.$parent.$$watchers = null;
}
This can be modified to fit your specific case.
Hope this helps!
Upvotes: 1
Reputation: 1870
I have a fork of Angular that lets you keep the watch in the $$watchers
but skip it most of the time. Unlike writing a custom directive that compiles your HTML it lets you use normal Angular templates on the inside, the difference is that once the inside is fully rendered the watches will not get checked any more.
Don't use it unless you really genuinely need the extra performance because it can have surprising behaviour.
Here it is:
https://github.com/r3m0t/angular.js/tree/digest_limit
Here's the directive you can use with it (new-once
):
https://gist.github.com/r3m0t/9271790
If you want the page to never update you can use new-once=1
, if you want it to sometimes update you can use new-once=updateCount
and then in your controller run $scope.updateCount++;
to trigger an update.
More information: https://github.com/Pasvaz/bindonce/issues/42#issuecomment-36354087
Upvotes: 1
Reputation: 14450
If you don't need angular dual-binding, have you tried a custom directive with a complie function where you construct HTML yourself by creating DOM from scratch without any angular dual-binded mechanisms ?
Upvotes: 0
Reputation: 1870
It sounds like you want to put the bindonce
directive on your ng-repeat
.
https://github.com/Pasvaz/bindonce
Upvotes: 0