Search code examples
angularjsangularjs-scope

Update angular scope without firing change events


Introduction

I' m writing checkbox tree directive using angular. Part of the behaviour is when I check checkbox in the middle of the tree, I need to unset all ancestor checkboxes and set all descendant checkboxes (see screenshot, transparent checkboxes are unchecked in fact).

https://www.dropbox.com/s/yx1bzqsamunmjpx/Screenshot%20from%202014-08-25%2018%3A39%3A44.png?dl=0

I'm using:

itemScope.$watch('checked', function setCheckboxes(newValue, oldValue) { ... });

For descendants everything works fine. I forEach child checkboxes and set them a new value, which in turn fires events for their descendants and so forth.

Problem is with ancestors. If I set parent checked value to false, it triggers event which sets all children to false which is not desired.

Question starts here:

I need to find a way to update (ancestor checkbox) model without firing event I subscribed with $watch. I know one way to wrap new value assignment in setTimeout(fn, 1), but I think it's not cool. What's the correct way of doing this?

Thanks!


Solution

  • You could use the ngChange directive on the checkbox to kick off the correct behavior, rather than $scope.watch. From the docs:

    The ngChange expression is only evaluated when a change in the input value causes a new value to be committed to the model.

    It will not be evaluated:

    • if the value returned from the $parsers transformation pipeline has not changed
    • if the input has continued to be invalid since the model will stay null
    • if the model is changed programmatically and not by a change to the input value