У меня есть следующий код:Изолированная сфера не обновляется
var testApp = angular.module('testApp', []);
testApp.directive('myDirective', function() {
return {
scope: {
child: '=child'
},
controller: function ($scope, $element, $attrs) {
$scope.$on('childChanged', function (event, newChild) {
if ($scope.child.id != newChild.id) {
alert("The child in the isolated scope is not updated!");
}
else {
alert("success");
}
});
}
};
});
testApp.controller('myController', function ($scope) {
$scope.parentObject = {childObject: {id:1}};
$scope.changeChild = function changeChild()
{
var newChild = { id: $scope.parentObject.childObject.id + 1};
$scope.parentObject.childObject = newChild;
//$scope.$apply(); //This solves the problem
$scope.$broadcast('childChanged', newChild);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div data-ng-app="testApp">
<div data-ng-controller="myController">
<div my-directive child="parentObject.childObject"></div>
<button data-ng-click="changeChild()">Change Child</button>
</div>
</div>
Объяснение:
- Я создаю изолированную область для директивы, с двухсторонним привязка к объекту (parentObject.childObject) родительской области.
- При нажатии на кнопку функция changeChild вызывается в myController. Эта функция заменит $ scope.parentObject.childObject другим ребенком и будет транслировать событие.
- Слушатель этого события находится в контроллере директивы. В прослушивателе мы проверяем, является ли дочерний объект в изолированной области ($ scope.child) тем же самым, что и тот, который был отправлен в событии (то есть, объект scope.parentObject.childObject родителя). Мы видим, что они не совпадают, то есть ребенок, которого мы получили в , выделенная область еще не обновлена.
Обратите внимание, что если я использую $ scope. $ Apply() перед трансляцией, тогда будет обновляться $ scope.child в контроллере директивы, однако это вызовет следующее исключение: «$ apply уже применяется прогресс".
Может кто-то, пожалуйста, помогите мне понять, что здесь происходит? Почему приложение $ scope. $ Применило помощь, даже если оно только выкидывало экскремент? Как это можно решить, не обращаясь к $ scope. $ Apply? Я хотел бы знать, есть ли способ гарантировать, что связанное свойство в изолированной области будет обновляться после его изменения в области родителя без необходимости передавать его в событии.
Спасибо
Спасибо, это действительно решает проблему. Я новичок в js и AngularJs, не могли бы вы объяснить, почему это решение работает? Является ли это лучшей практикой для таких случаев? (Извините, я не могу проголосовать, я тоже новичок в stackoverflow ...) – user2051749
@ user2051749 В вашем примере, когда вы транслировали newChild angularjs, во время цикла дайджеста и newChild не обновлялся, вам нужно вызвать еще один цикл дайджеста, чтобы новое значение brodcast (http://stackoverflow.com/questions/16066239/defer-angularjs-watch-execution-after-digest-raising-dom-event). Я скорее использую $ watch в директиве вместо $ broadcast, см. Здесь http://jsbin.com/nibopa/1/edit – sylwester
Спасибо за объяснение. Я попробовал использовать $ watch перед отправкой вопроса, но получил «undefined» как в newValue, так и в oldValue. Не знаю, почему, так как ваш пример (jsbin.com/nibopa/1/edit) работает отлично, и код кажется таким же, как мой ... :( После того, как я увидел следующее сообщение, я попытался использовать вместо этого $ broadcast: http://www.benlesh.com/2013/10/title.html – user2051749