为Angularjs指令实现更改处理程序

时间:2014-05-11 09:04:17

标签: javascript angularjs angularjs-directive

我尝试创建一个自定义指令,提供与input控件类似的更改通知。使用输入控件,您可以执行以下操作:

<input type="text" ng-model="foo" ng-change="bar(a,b)">

在这种情况下,每次更改bar的值时,只会调用ng-change指定的foo函数。我创建了一个自定义指令,我想添加相同类型的更改通知。

<div my-directive ng-model="foo" ng-change="bar(a,b)"></div>

我首先尝试在范围中包含更改处理程序然后执行它,但是在范围中包含它会导致在实例化时调用它12次,而在更改时调用12次因为我相信这是多久一次正在评估属性。

return {
  templateUrl: '...',
  restrict: 'A',
  require: '^ngModel',
  scope: {
    ngModel: '=',
    ngChange: '='
  },
  link: function postLink(scope, element, attrs) {
    if(angular.isFunction(scope.ngChange) {
      scope.ngChange(); // bar is called 12 times
    }
  }
}

然后我查看了Angular源代码,看到他们在input上评估了更改处理程序的属性值。我试图这样做,但指定的函数似乎永远不会被调用。

return {
  templateUrl: '...',
  restrict: 'A',
  require: '^ngModel',
  scope: {
    ngModel: '='
  },
  link: function postLink(scope, element, attrs) {
    scope.$eval(attrs.ngChange);  // bar is never called
  }
}

这样做的正确方法是什么?

2 个答案:

答案 0 :(得分:1)

如果您想在每次更改模型时致电ngChange,您可以观看模特并在观看回拨中致电ngChange

Plunk here

答案 1 :(得分:0)

使用下一个

return {
    templateUrl: '...',
    restrict: 'A',
    require: '^ngModel',
    scope: {
        ngModel: '=',
        ngChange: '&'
    },
    link: function postLink(scope, element, attrs) 
    {
        scope.changingModel = function(newValue)
        {
             scope.ngModel = newValue;
             scope.ngChange();
        }
    }
}

'&安培;'用于绑定表达式。这将使你的ngChange被执行。

使用观察者很贵。观察者暗示角度将检查变量的变化很多次。如果您的变量是一个数组,那么更糟糕的是,您必须非常小心更新变量的方式,并确保不更新变量,同时更新整个变量。类似的东西:

var newValue = getMyNewValue($scope.foo);
$scope.foo = newValue;

'link'功能在任何绑定之前执行。请注意这一点。

我一直有一个稍微不同的问题,我认为你会面对,我希望其他人能为我们两个人解决。

在我的情况下,我正在使用像

这样的东西
<div my-directive ng-model="foo" ng-change="bar(foo)"></div>

ngChange()的执行将在父范围内进行,即在定义条形函数的范围内。这是预期的行为。但是将执行,就像您的模型在父范围中没有更改一样。我的意思是,bar(foo)将使用旧值foo而不是newValue执行。