2014-01-10 4 views
0

У меня есть настраиваемая директива, которая слушает, чтобы изменять события на входах, которые пузырятся (используя функцию jQuery delegate). У меня проблема, когда слушатель запускается до обновления ng-моделей (в Chrome), что означает, что данные устарели в моей директиве. Кажется, он работает в Firefox. Это связано с приложением слушателей? Пример:AngularJS директива гонка состояние (порядок слушателей?)

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.foo должен быть обновлен. ngChange вызывается первым в FF, второй в Chrome, где myChange вызывается первым Chrome и вторым в FF.

Добавление вызова $timeout заставляет его работать должным образом ($scope.foo имеет значение, которое я ожидаю), но это похоже на крупный взлом.

Рабочая plunkr кода выше: http://plnkr.co/edit/Y1TWGKlkimS3H5Lqaisw

+0

Возможны ли ураганные jqLite [версии .on()] (http://api.jquery.com/on/) в соответствии с вашими потребностями? Тогда вам не придется пытаться согласовывать синхронизацию между jQuery и Angular в браузерах, что явно имеет свои хитрые места. – KayakDave

+0

@KayakDave Это не идеально для того, что я пытаюсь сделать. Я использую функцию делегата, чтобы получить старую «живую» функциональность. Есть также тонны входных данных, и я предпочитаю прослушивать события, которые пузырь затем добавляют тонны ng: click и ng: change – mmattax

+0

$ timeout может быть вашим лучшим выбором. Я знаю, что вы имеете в виду, чувствуя себя взломанным. Но поскольку (с таймаутом 0) он добавляет новое событие в самый конец очереди событий браузера - кажется, он эффективно делает то, что вы хотите. И это не редкое решение. – KayakDave

ответ

0

вы пробовали изменения $ элемента $ ($ элемент)? См. Ниже ...

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; 
    }) 
    } 
    } 

}]); 
+0

Просто попробовал, это, похоже, не имеет значения. $ element уже является объектом jQuery. – mmattax

Смежные вопросы