Reputation: 148524
I have created a simple TODO app with AngularJS.
So I have here a list of TODOs. I can delete , set as completed , and add new ones.
I can also edit the title via double clicking the bold text. And now - a text input will appear instead:
Basically , each row ( under the ng-repeat) has an invisible input which I play with its visibilkity :
<li ng-repeat="todo in vm.todos....." ...>
<div ng-hide="vm.isTheEdited(todo)"> //this is "read" mode
....show checkbox + Label + Delete button
</div>
<input ... show="vm.isTheEdited(todo)".... /> // this is the "edit" mode
</li>
All OK
But I saw this code which counts watchers in an App .
So I enhanced it to show unique items and in a string way.
(All I did was adding) :
Array.prototype.unique = function(a){
return function(){ return this.filter(a) }
}(function(a,b,c){ return c.indexOf(a,b+1) < 0 })
console.log(getWatchers().unique().length);
console.log(getWatchers().unique().map(function (a){return a.exp;}));
)*
This is not important.
The important thing is that it has many duplicates watchers !!!
Look at the results :
Question why do I have so many duplicates entries and how can I reduce the number of the watchers? (and eliminate dups)
All I did was to use ng-show and hide via some value of function.
Upvotes: 2
Views: 722
Reputation: 1723
In fact I don't think there isn't any duplicate: both ngShow an ngHide create a watcher and you can't do anything to avoid that using native directives: you should expect at least two watcher for each row in this case.
The only way to remove watchers (all of them) is to create a custom directive that:
Example:
module.directive('myClick', function() {
return {
link: function(scope, element) {
var span = element.find('span'),
input = element.find('input');
input.hide();
span.on('dblclick', function() {
if (span.is(':visible')) {
span.hide();
input.show();
input.val(span.text());
}
});
input.on('keypress', function(e) {
if (e.which === 13) {
input.hide();
span.show();
span.text(input.val());
}
});
}
}
});
Html:
...
<div ng-repeat="todo in vm.todos" my-click>
<span>{{todo}}</span><input>
</div>
...
Upvotes: 1