Royi Namir
Royi Namir

Reputation: 148524

How can I get rid of all duplicate watches in AngularJS?

I have created a simple TODO app with AngularJS.

enter image description here

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:

enter image description here

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 :

enter image description here

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

Answers (1)

Mario Lamacchia
Mario Lamacchia

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:

  • hides the label and show the input on double click
  • shows the label and hide the input when pressing enter

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

Related Questions