AngularJS指令竞争条件(侦听器的顺序?)

时间:2014-01-10 20:47:13

标签: javascript angularjs

我有一个自定义指令,用于监听冒泡的输入上的更改事件(使用jQuery的delegate函数)。我遇到了一个问题,即在ng-models更新之前(在Chrome中)触发了侦听器,这意味着数据在我的指令中是陈旧的。它似乎在Firefox中工作。这是否与附加的听众顺序有关?一个例子:

HTML:

<div my:change="myChange()">
    <input type="checkbox" ng:change="ngChange()" ng:model="foo" ng:true-value="foo" ng:false-value="bar" />
</div>

和JS:

app.controller('MainCtrl', function($scope) {

  $scope.foo = 'foo'; // Source
  $scope.bar = 'foo'  // w/o $timeout
  $scope.bar2 = 'foo' // with $timout

  $scope.ngChange = function() {

    console.log('ngChange');
  }

})
.directive('myChange', ['$timeout', function($timeout) {
  return {
    link: function($scope, $element, $attrs) {

     $element.delegate('input', 'change', function(event) {

       console.log('myChange')

       // A value was changed, let's update the value from the model.
       $timeout(function() {
         $scope.bar2 = $scope.foo;
       })

       $scope.bar = $scope.foo;
     })
    }
  }

}]);

选中此复选框后,应更新$scope.foongChange首先在FF中调用,在Chrome中调用第二,其中myChange称为第一个Chrome,第二个称为FF。

添加$timeout调用使其按预期工作($scope.foo具有我期望的值),但这感觉就像是一个主要的黑客。

以上代码的工作plunkr:http://plnkr.co/edit/Y1TWGKlkimS3H5Lqaisw

1 个答案:

答案 0 :(得分:0)

您是否尝试将$ element更改为$($ element)?见下文......

app.controller('MainCtrl', function($scope) {

  $scope.foo = 'foo'; // Source
  $scope.bar = 'foo'  // w/o $timeout
  $scope.bar2 = 'foo' // with $timout

  $scope.ngChange = function() {

    console.log('ngChange');
  }

})
.directive('myChange', ['$timeout', function($timeout) {
  return {
    link: function($scope, $element, $attrs) {

     $($element).delegate('input', 'change', function(event) {

       console.log('myChange')

       // An value was changed, let's update the value from the model.
       $timeout(function() {
         $scope.bar2 = $scope.foo;
       })

       $scope.bar = $scope.foo;
     })
    }
  }

}]);