Директивы AngularJS: изменение $scope, не отраженное в пользовательском интерфейсе
Я пытаюсь создать некоторые пользовательские элементы с помощью AngularJS и связать с ним некоторые события, тогда я заметил, что $scope.var не будет обновлять интерфейс при использовании в функции привязки.
Вот упрощенный пример, описывающий задачу:
HTML:
<!doctype html>
<html ng-app="test">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body>
<div ng-controller="Ctrl2">
<span>{{result}}</span>
<br />
<button ng-click="a()">A</button>
<button my-button>B</button>
</div>
</body>
</html>
JS:
function Ctrl2($scope) {
$scope.result = 'Click Button to change this string';
$scope.a = function (e) {
$scope.result = 'A';
}
$scope.b = function (e) {
$scope.result = 'B';
}
}
var mod = angular.module('test', []);
mod.directive('myButton', function () {
return function (scope, element, attrs) {
//change scope.result from here works
//But not in bind functions
//scope.result = 'B';
element.bind('click', scope.b);
}
});
DEMO: http://plnkr.co/edit/g3S56xez6Q90mjbFogkL?p=preview
В основном, я привязываю событие click
к my-button
и хочу изменить $scope.result
, когда пользователь нажал кнопку B (аналогично ng-click:a()
на кнопке A). Но если я сделаю так, представление не будет обновлено до нового $scope.result
.
Что я сделал неправильно? Спасибо.
Ответы
Ответ 1
Обработчики событий называются "вне" Angular, поэтому, хотя ваши свойства $scope
будут обновлены, представление не будет обновляться, поскольку Angular не знает об этих изменениях.
Вызвать $scope.$apply()
в нижней части обработчика событий. Это вызовет цикл дайджест, и Angular заметит изменения, внесенные вами в $scope
(из-за $watches
, который Angular установлен из-за использования {{ ... }}
в вашем HTML) и обновить представление.
Ответ 2
Это может быть также результатом различных проблем, но с теми же симптомами.
Если вы уничтожаете родительскую область, назначенную для представления, ее изменения никак не повлияют на представление даже после вызова $apply()
. См. пример - вы можете изменить значение представления через ввод текста, но когда вы нажмете Destroy parent scope!, модель больше не обновляется.
Я не считаю это ошибкой. Это скорее результат слишком хакерского кода в приложении: -)
Я столкнулся с этой проблемой при использовании Angular Bootstrap modal. Я попытался открыть второй модальный с объемом первого. Затем я сразу же закрыл первый способ, который вызвал разрушение родительской области.
Ответ 3
использовать таймаут
$timeout (function() {
код....
}, 0);