How to implement an ng-change for a custom directive

后端 未结 5 1067
滥情空心
滥情空心 2020-12-02 20:13

I have a directive with a template like

5条回答
  •  天涯浪人
    2020-12-02 20:37

    tl;dr

    In my experience you just need to inherit from the ngModelCtrl. the ng-change expression will be automatically evaluated when you use the method ngModelCtrl.$setViewValue

    angular.module("myApp").directive("myDirective", function(){
      return {
        require:"^ngModel", // this is important, 
        scope:{
          ... // put the variables you need here but DO NOT have a variable named ngModel or ngChange 
        }, 
        link: function(scope, elt, attrs, ctrl){ // ctrl here is the ngModelCtrl
          scope.setValue = function(value){
            ctrl.$setViewValue(value); // this line will automatically eval your ng-change
          };
        }
      };
    });
    

    More precisely

    ng-change is evaluated during the ngModelCtrl.$commitViewValue() IF the object reference of your ngModel has changed. the method $commitViewValue() is called automatically by $setViewValue(value, trigger) if you do not use the trigger argument or have not precised any ngModelOptions.

    I specified that the ng-change would be automatically triggered if the reference of the $viewValue changed. When your ngModel is a string or an int, you don't have to worry about it. If your ngModel is an object and your just changing some of its properties, then $setViewValue will not eval ngChange.

    If we take the code example from the start of the post

    scope.setValue = function(value){
        ctrl.$setViewValue(value); // this line will automatically evalyour ng-change
    };
    scope.updateValue = function(prop1Value){
        var vv = ctrl.$viewValue;
        vv.prop1 = prop1Value;
        ctrl.$setViewValue(vv); // this line won't eval the ng-change expression
    };
    

提交回复
热议问题