Search code examples
angularjs-components

Why doesn't my AngularJS component react to attribute value changes?


I've seen several questions about topics like this here on SO and on the web at large. Specifically, I tried to follow one clear example but can't get it to work in my code. I have a plunker which I hope shows my problem; it follows that example but doesn't work.

  • The component displays one check box for each item in a list (specified as an attribute, should be a one-way binding as the component never changes the value to communicate to the page)
  • When one and only one check box is checked, it calls a callback function to tell the page that the Xor of the bits is true
  • There is a "call in" function which clears all the check boxes. (This works but is kind of irrelevant, it's a vestige of an earlier Plunker for a different problem)
  • There is a Add Bit button on the page which adds an item to the list of bits for the component to display
  • There is a $watch() in the component controller on the list of bits to display. Right now it just logs that it was called but something closer to my end goal would be to make sure that the new checkbox is initially set rather than cleared.

The $watch() fires as the page loads (the component is created). However, when I click the button and add a bit, the ng-repeat which creates the check boxes fires but the $watch() does not.


Solution

  • Use a watch collection. Read about it here. The solution applied to your plunkr would be this

     $scope.$watchCollection(
          "vm.myBits",
          function(newValue, oldValue) {
            console.log("a. new bit");
        });

    An update version of your plunk

    You can also use "deep" object checking by adding a third parameter of 'true' to the watch. However this is very "expensive" and not recommended once watchCollection was introduced in 1.2.x

     $scope.$watch(
          "vm.myBits",
          function(newValue, oldValue) {
            console.log("a. new bit");
        },true); // The TRUE is a deep checking and also works but is "expensive"