1

No matter what I tried from answers to the same question, I can't get this to work. notice I'm also using a tr-state checkbox directive.

https://plnkr.co/edit/mBy0mm0XZNzo9EnsmL9Q?p=preview

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  var vm = this;
  
   vm.flags = [
        { field: "PaymentMade", title: "Payment Made", isSeaAir: false, filter: null },
        { field: "isInTransit", title: "In Transit", isSeaAir: false, filter: null },
        { field: "Docked", title: "Docked", isSeaAir: false, filter: null },
        { field: "isDockedPartial", title: "Docked Partial", isSeaAir: true, filter: null },

    ];
  $scope.$watch('vm.flags' , function handleFlagssChange(newVla, oldVal) {
        console.log("flags changed");
    });
});

app.directive('indeterminate', [function () {
    return {
        require: '?ngModel',
        link: function (scope, el, attrs, ctrl) {
            var truthy = true;
            var falsy = false;
            var nully = null;
            ctrl.$formatters = [];
            ctrl.$parsers = [];
            ctrl.$render = function () {
                var d = ctrl.$viewValue;
                el.data('checked', d);
                switch (d) {
                    case truthy:
                        el.prop('indeterminate', false);
                        el.prop('checked', true);
                        break;
                    case falsy:
                        el.prop('indeterminate', false);
                        el.prop('checked', false);
                        break;
                    default:
                        el.prop('indeterminate', true);
                }
            };
            el.bind('click', function () {
                var d;
                switch (el.data('checked')) {
                    case falsy:
                        d = truthy;
                        break;
                    case truthy:
                        d = nully;
                        break;
                    default:
                        d = falsy;
                }
                ctrl.$setViewValue(d);
                scope.$apply(ctrl.$render);
            });
        }
    };
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="plunker" ng-controller="MainCtrl as vm">
  <label>Flags: </label>
        <label class="btn btn-info" ng-repeat="f in vm.flags" style="margin-right:5px;">
            <input type="checkbox" ng-model="f.filter" indeterminate />
            {{f.title}} | {{f.filter}}
        </label>
</body>
boruchsiper
  • 2,016
  • 9
  • 29
  • 53

1 Answers1

1

You need to add third parameter true, to check correct for object equality.

$scope.$watch('vm.flags' , function handleFlagssChange(newVla, oldVal) {
    console.log("flags changed");
}, true);

Angular documentation

When objectEquality == true, inequality of the watchExpression is determined according to the angular.equals function. To save the value of the object for later comparison, the angular.copy function is used. This therefore means that watching complex objects will have adverse memory and performance implications.

Nikola Andreev
  • 624
  • 4
  • 18