AngularJS 指令 $watch 双向绑定 [英] AngularJS directive $watch two-way binding

查看:24
本文介绍了AngularJS 指令 $watch 双向绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图通过双向数据绑定属性 ('=') 区分内部更改和外部更改.

换句话说:如果更改是内部的(即范围变量在控制器或链接函数中更改),我不想 $watch 触发该值.

这里有一些代码说明了我的问题:

HTML

 

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

Javascript

app.directive('mydemo', function () {返回 {限制:'E',范围: {值:="},模板:<div id='mydiv'>点击更改值属性</div>值:{{value}}",链接:功能(范围,榆树){scope.$watch('value', function (newVal) {//如果更改来自changeValue函数,则不监听//监听变化是否来自输入元素});//否则在此处保持任何模型同步.var changeValue = function(){scope.$apply(函数(){scope.value = "来自 changeValue 函数";});}elm.bind('click', changeValue);}}})

现场演示:http://jsfiddle.net/B7hT5/11/

知道我能区分谁吗?

解决方案

无法区分这两个事件,因此您必须自己实现该行为.

每当您进行内部"更改时,我都会设置一个标志,然后在手表中进行检查.

例如:

link: function (scope, elm){内部变量 = 假;scope.$watch('value', function (newVal) {如果(内部)返回内部=假;//你想在外部变化时运行的任何代码都在这里.控制台日志(新值);});var changeValue = function(){范围.$应用(函数(){内部 = 真;//标记内部更改scope.value = "来自 changeValue 函数";});}elm.bind('click', changeValue);}

请参阅更新的小提琴.

您的替代(更复杂)方法是创建一个使用 ngModel API 的自定义指令.这区分了 DOM -> 模型(外部)和模型 -> DOM(内部)更改.不过,我认为这里没有必要.

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?

解决方案

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.

这篇关于AngularJS 指令 $watch 双向绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆