I am currently facing an issue with a custom directive that is listening to change events on input elements using jQuery's delegate function. The problem arises in Chrome where the listener fires before the ng-models update, resulting in stale data within my directive. Interestingly, it seems to work fine in Firefox. Could this be related to the order of listeners being attached? Here is an example:
The HTML:
<div my:change="myChange()">
<input type="checkbox" ng:change="ngChange()" ng:model="foo" ng:true-value="foo" ng:false-value="bar" />
</div>
And the 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;
})
}
}
}]);
When the checkbox is checked $scope.foo
should be updated. the ngChange
gets called first in FF, second in Chrome, where as myChange
gets called first Chrome and second in FF.
Adding the $timeout
call makes it work as expected ($scope.foo
has the value I expect), but that feels like a major hack.
Working plunkr of code above: http://plnkr.co/edit/Y1TWGKlkimS3H5Lqaisw