AngularJS directive $watch two-way binding

匿名 (未验证) 提交于 2019-12-03 00:50:01

问题:

I'm trying to distinguish between internal change and an external change with a two-way data-bound attribute ('=').

In other words: I don't want to $watch to fire on the value if the change was internal (i.e. the scope variable was changed in the controller or in the link function).

Here some code that illustrates my problem:

HTML

 <div ng-app="myApp">             <div ng-controller="MainCtrl">      <input ng-model="value"/>      <mydemo value="value"></mydemo>    </div>  </div> 

Javascript

app.directive('mydemo', function () {   return {     restrict: 'E',     scope: {       value: "="     },     template: "<div id='mydiv'>Click to change value attribute</div> Value:{{value}}",      link: function (scope, elm)      {             scope.$watch('value', function (newVal) {       //Don't listen if the change came from changeValue function       //Listen if the change came from input element        });       // Otherwise keep any model syncing here.        var changeValue = function()       {         scope.$apply(function ()         {           scope.value = " from changeValue function";         });       }        elm.bind('click', changeValue);     }   } }) 

Live demo: http://jsfiddle.net/B7hT5/11/

Any idea who can I distinguish?

回答1:

There's no option to distinguish between these two events, so you'll have to implement that behaviour yourself.

I would do it by setting a flag whenever you make a change "internally", then checking for it in the watch.

For example:

link: function (scope, elm){          var internal = false;    scope.$watch('value', function (newVal) {     if(internal) return internal = false;     // Whatever code you want to run on external change goes here.     console.log(newVal);   });    var changeValue = function(){     scope.$apply(function (){       internal = true; // flag internal changes       scope.value = " from changeValue function";                                   });   }    elm.bind('click', changeValue); } 

See the updated fiddle.

Your alternative (more complex) approach, is creating a custom directive that uses the ngModel API. That distinguishes between DOM -> Model (external) and Model -> DOM (internal) changes. I don't think it's necessary here, though.



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!