0

I have a directive like so:

.directive('checkMeIfApplyAll', function($timeout) {
    return {
        link: function(scope, element, attrs) {
            scope.$watch(attrs.checkMeIfApplyAll, function(value) {
                debugger;
                if(value === true) {
                    element.prop('checked', true);
                }
                else {
                    element.prop('checked', false);
                }
            });
        }
    };

And here is the corresponding html snippet:

<tr 'ng-repeat'='permission in category.permissions'>
  <input type='checkbox' 'ng-model'='permission.show' 'check-me-if-apply-all'= 'category.allChecked'>
</tr>

Notice that if the value of category.allChecked changes, the watcher function is triggered. As you can see, if that value is true, then using jquery, I can check the checkbox. However, as you can see in the html snippet, each checkbox has been assigned a model e.g. 'permission.show'. And what I really want to do is change the model value in the directive and not simply the property of element. How can I access the ng-model attribute of the element inside of the watch function?

John Slegers
  • 45,213
  • 22
  • 199
  • 169
sq1020
  • 1,000
  • 2
  • 9
  • 15

2 Answers2

1

Let's go simple. I think you don't need directive for this and $watch should not be overused.

<tr ng-repeat='permission in category.permissions'>
  <input type='checkbox' ng-model='permission.show' 
    ng-checked='category.allChecked'>
</tr>

To access model in the directive, just access scope.category.permissions[INDEX].show

I haven't tested the above since there is no plnkr provided.

allenhwkim
  • 27,270
  • 18
  • 89
  • 122
  • I had tried this before but if category.allChecked changes by some user action, the permission.show model is not updated even though the DOM i.e. the checkboxes are. See http://stackoverflow.com/questions/16601018/angularjs-ng-model-not-binding-to-ng-checked-for-checkboxes – sq1020 Jul 18 '14 at 22:21
1

You can use ngModelController:

.directive('checkMeIfApplyAll', function($timeout) {
    return {
        require: 'ngModel',
        link: function(scope, element, attrs, ngModel) {
            scope.$watch(attrs.checkMeIfApplyAll, function(value) {
                debugger;
                if(value === true) {
                    element.prop('checked', true);
                }
                else {
                    element.prop('checked', false);
                }

                // Set value like this
                ngModel.$setViewValue(value);
            });
        }
    };
Bogdan
  • 43,166
  • 12
  • 128
  • 129
  • This works perfectly but I was thinking that with ngModel.$setViewValue(value), I wouldn't need the code before it which checks or unchecks the checkboxes using jquery. However, changing the model value doesn't seem to effect whether the checkboxes are checked or not even though they are bound to that property. Any idea why? – sq1020 Jul 18 '14 at 19:46
  • Are you referring the the checkbox you have the `ngModel` bound to? You want it to be checked if the value of `permission.show` is true, or do you have other elements that are dependant on the model's value? Perhaps you could post some more code so I can get a better view of what you are tring to achieve. – Bogdan Jul 18 '14 at 19:52
  • So I realized that when you call $setViewValue(value), the model gets updated but the DOM does not so the checkboxes will remain as they were. You need to add ngModel.$render() in order for the DOM to update. I updated your answer accordingly. Thanks! – sq1020 Jul 18 '14 at 22:25