ng-click比Angular数据绑定更快

时间:2014-03-20 11:22:17

标签: angularjs angularjs-directive

我想创建一个自己的复选框输入控件。它应该像<input type="checkbox" ng-model="check" ng-change=”handler()”>一样具有不同的外观。我创建了一个带有隔离范围的自定义指令,而不是ng-model我在指令和控制器的范围变量之间使用了绑定'='而不是ng-change我在指令之间使用了绑定'&amp;' - 单击处理程序和控制器的作用域方法(处理程序)。

控制器

.controller('MyCtrl', ['$scope', function MyCtrl($scope) {
  $scope.check = false;
  $scope.messages = [];

  $scope.onCheckChange = function(value) {
    $scope.messages.push('onCheckChange: $scope.check == ' + $scope.check + ' value == ' + value);
  }
}])

指令

.directive('myCheckbox', function() {
  return {
    restrict: 'A',
    scope: {
        title:           '@',
        value:           '=',
        onChangeHandler: '&'
    },
    template:
      '<span class="my-checkbox"> ' +
        '<span class="tickbox" ng-click="click()" ng-class="{\'ticked\': value}" title="{{title}}"></span>' +
      '</span>',
    link: function(scope, element, attrs) {
      scope.click = function() {
        scope.value = ! scope.value;
        scope.onChangeHandler({value: scope.value});
      };
    }
  };
})

工作插件在这里http://plnkr.co/edit/oIQbqSzcWUShfdTyDBTl?p=preview

事情正如我所期望的那样有一个例外:

  1. 用户点击复选框,调用指令scope.click(),将scope.value设置为新的复选框值,并将此新值作为参数发送给控制器的$scope.onCheckChange()
  2. 但是在控制器的方法$scope.onCheckChange()中,$scope.check变量包含新值,但是前一个值,尽管参数'value'已经是新值
  3. '一段时间'后,即使$scope.check变量设置为新值。似乎来自on-click()的调用在某种程度上比Angular数据绑定“更快”。我已经考虑了范围。$ apply但不认为是这种情况 - Angular很好地处理了绑定,但它需要时间才能通过... ...
  4. 问题:

    1. 为什么会这样?我想知道这是为了避免一些令人讨厌的惊喜,如果有一些人在Angular的深处等我。类似的,没有回答的问题: angular directive data binding happens after ng-change
    2. 有没有办法让新的复选框指令“监听”原生ng-modelng-changeng-disable?我想以与原生指令相同的方式处理自定义指令。或者它只是绑定的名称?

2 个答案:

答案 0 :(得分:0)

我仍然不知道为什么它正在发生,但我找到了一个解决方法:将处理程序包装到$timeout块而没有特定的延迟。如果它是指令的处理程序或控制器中的处理程序都无关紧要,两者都可以解决问题。 $timeout给角度时间带来绑定通过。

无论如何,我仍然很好奇为什么会这样。

答案 1 :(得分:0)

使用ngModel http://plnkr.co/edit/IPWhZ8?p=preview

您的问题是因为您的处理程序是在摘要周期更新$ scope.check之前触发的。