AngularJS – сброс значения $ scope.value не изменяет значение в шаблоне (случайное поведение)
Взгляните на пример на http://jsfiddle.net/2NJ7y/3/ (версия AngularJS 1.0.1). Существует простое приложение, которое ждет ввода счастливого номера. Если число равно 7, я сброшу удачное число до нуля. Если я введу номер 7 несколько раз, иногда / случайно, счастливое число останется в поле ввода. Зачем? Как это поведение решается? Благодарю.
- Как хранить данные в локальном хранилище с помощью Angularjs?
- Выделение отфильтрованного результата в AngularJS
- angularjs не может найти каталог шаблонов, колбу в качестве бэкэнд
- Получение MathJax для обновления после изменений в модели AngularJS
- Двоичные файлы повреждены - Как загрузить двоичные файлы с помощью AngularJS
- Как отменить запрос $ http в AngularJS?
- Как выбрать элемент по имени classа с помощью jqLite?
- Как вернуть изображение из $ http.get в AngularJS
Я сделал некоторую отладку.
Во-первых, для меня счастливое число остается в поле ввода не случайно.
enter 3 (model==3, input==3)
=> enter 7 (alert, model==null, input="")
=> enter 3 (model==3, input==3)
=> remove 3 (model=="", input=="")
=> enter 7 (alert, model==null, input="")
=> enter 7 (alert, model==null, input="7")
7 остаются в поле ввода, только если предыдущее значение модели было нулевым.
Что происходит : когда вы вводите входное событие 7, которое обрабатывается функцией прослушивателя входной директивы . Функция прослушивателя вызывает $ setViewValue . $ setViewValue устанавливает $ viewValue, $ modelValue, значение модели и вызывает $ viewChangeListeners (ngChangeDirective просто добавляет обработчик в $ viewChangeListeners). Отобразится предупреждение, значение luckynumber равно null. В конце концов, если luckynumber отличается от предыдущего значения предыдущим грязным проверяющим $ watch handler и $ render , вызываются.
В моих примерах $ render вызывается, если предыдущее значение модели было «3» или «». Если предыдущее значение модели было равно null, рендер не вызывается.
Почему $ timeout с задержкой 0 работает : когда вы вызываете $ timeout с функцией задержки 0 с изменением числа удачи в null, откладывается в конце очереди событий (все javascript в браузере выполняется в одном streamе). $ viewChangeListener не изменяет значение модели от 7 до нуля. $ digest заканчивается. Затем вызывается $ timeout handler. Значение модели равно null. $ watch handler и $ render. $ render устанавливает значение ввода в значение “”.
Наконец, решение. Используйте $ watch вместо ng-change:
$scope.$watch('luckynumber', function() { if ($scope.luckynumber == 7) { alert('The lucky number mustn\'t be equal 7.'); $scope.luckynumber = null; } })
Скрипт .
Этот другой ответ SOV @ Valentyn заставил меня подумать о том, чтобы попытаться решить этот вопрос.
Если вы просто положите
$scope.luckynumber = undefined;
перед предупреждением вы не устраняете состояние гонки, но вы меняете его так, чтобы 7 правильно очищался, но иногда вы получаете предупреждение дважды.
Если код предупреждения заменен чем-то идемпотентным, например, изменением DOM для отображения ошибки, тогда эта проблема не будет иметь значения.