Смотрите переменную и измените ее
В AngularJS у меня есть директива, которая отслеживает переменную области видимости. Когда переменная содержит определенные данные, мне нужно немного изменить эту переменную. Проблема заключается в том, что когда я изменяю переменную, которую мой $watch
запускается снова. Поэтому я заканчиваю непрерывный цикл.
scope.$watch('someVar', function(newValue, oldValue) {
console.log(newValue);
scope.someVar = [Do something with someVar];
});
Это снова вызывает запуск $watch
, что имеет смысл. Но мне нужен способ изменить наблюдаемую переменную. Есть ли способ сделать это?
Ответы
Ответ 1
Когда переменная просматривается для изменений с помощью $scope.$watch
, angular проверяет, изменилась ли ссылка. Если он имеет, то обработчик $watch
выполняется для обновления представления.
Если вы планируете изменить переменную области видимости в обработчике $watch, она вызовет цикл бесконечного цикла $digest, потому что ссылка переменной области изменяется каждый раз, когда она вызывается.
Трюк, чтобы обойти бесконечную проблему дайджеста, - сохранить ссылку внутри вашего обработчика $watch
, используя angular.copy(docs):
scope.$watch('someVar', function(newValue, oldValue) {
console.log(newValue);
var someVar = [Do something with someVar];
// angular copy will preserve the reference of $scope.someVar
// so it will not trigger another digest
angular.copy(someVar, $scope.someVar);
});
Примечание. Этот трюк работает только для ссылок на объекты. Он не будет работать с примитивами.
В целом, не рекомендуется обновлять переменную $watched
внутри своего собственного прослушивателя $watch
. Однако иногда это может быть неизбежным.
Ответ 2
Внутри функции используется , если условие для продолжения продолжается для цикла
scope.$watch('someVar', function(newValue, oldValue) {
if(newValue!==oldValue) {
console.log(newValue);
scope.someVar = [Do something with someVar];
}
});
Ответ 3
Вот как работает грязная проверка. Каждый раз, когда что-то на $scope
меняет Angular, он будет вращаться по всему, что привязано к сфере действия, и будет продолжать делать это до тех пор, пока не будет никаких изменений.
Если вы хотите сделать что-то подобное, вам нужно убедиться, что ваша функция $watch
является идемпотентной. Вам нужно будет посмотреть как newValue
, так и oldValue
и выяснить, что вы уже применили изменения к своей переменной в этом цикле $digest
. Как вы можете это сделать, это немного зависит от того, какие изменения вы делаете с someVar
.
Вообще говоря, изменение наблюдаемой переменной в функции часов, к сожалению, не очень хорошая идея.
Ответ 4
да, вы можете отменить его таким образом
var wathcer = scope.$watch('someVar', function(newValue, oldValue) {
console.log(newValue);
scope.someVar = [Do something with someVar];
});
wathcer(); // clear the watch
Ответ 5
вы можете управлять им с помощью переменной bool
$scope.someVarChanged = false;
scope.$watch('someVar', function(newValue, oldValue) {
console.log(newValue);
$scope.someVarChanged = !$scope.someVarChanged!;
if($scope.someVarChanged) {
scope.someVar = [Do something with someVar];
}
});