В AngularJS вы могли указать наблюдателей, чтобы наблюдать изменения в переменных области, используя $watch
функцию $scope
. Что эквивалентно наблюдению за изменениями переменных (например, в компонентных переменных) в Angular?
213
Ответы:
В Angular 2 обнаружение изменений происходит автоматически ...
$scope.$watch()
и$scope.$digest()
RIPК сожалению, раздел «Обнаружение изменений» в руководстве разработчика еще не написан (в нижней части страницы « Обзор архитектуры» в разделе «Прочие материалы» есть место для заполнения).
Вот мое понимание того, как работает обнаружение изменений:
setTimeout()
внутри наших компонентов, а не что-то вроде$timeout
... потому чтоsetTimeout()
залатана обезьяна.ChangeDetectorRef
.) Эти детекторы изменений создаются, когда Angular создает компоненты. Они отслеживают состояние всех ваших привязок, для грязной проверки. В некотором смысле они аналогичны автоматическим,$watches()
которые Angular 1 будет устанавливать для{{}}
привязок к шаблону.В отличие от Angular 1, график обнаружения изменений является ориентированным деревом и не может иметь циклов (это делает Angular 2 намного более производительным, как мы увидим ниже).
onPush
стратегию обнаружения изменений ни для одного из ваших компонентов), каждый компонент в дереве проверяется один раз (TTL = 1) ... сверху, в порядке глубины. (Хорошо, если вы находитесь в режиме разработки, обнаружение изменений запускается дважды (TTL = 2). Подробнее об этом см. ApplicationRef.tick () .) Он выполняет грязную проверку всех ваших привязок, используя эти объекты детектора изменений.Если данные компонента, которые вы хотите просмотреть, являются примитивным входным свойством (String, boolean, number), вы можете реализовать их,
ngOnChanges()
чтобы получать уведомления об изменениях.Если свойство input является ссылочным типом (объект, массив и т. Д.), Но ссылка не изменилась (например, вы добавили элемент в существующий массив), вам нужно будет реализовать
ngDoCheck()
(см. Этот SO-ответ для получения дополнительной информации). на этом).Вам следует только изменять свойства компонента и / или свойства компонентов-потомков (из-за реализации обхода одного дерева - т. Е. Однонаправленного потока данных). Вот плункер, который нарушает это. Трубки с состоянием также могут сбить вас с толку.
Другие ссылки, чтобы узнать больше:
onPush
.источник
host
Документацию «Host Listeners» в документе DirectiveMetadata API . В нем объясняется, как прослушивать глобальные события изнутри угловой зоны (поэтому обнаружение изменений будет срабатывать по желанию). У этого ответа есть рабочий поршень.Это поведение теперь является частью жизненного цикла компонента.
Компонент может реализовать метод ngOnChanges в интерфейсе OnChanges, чтобы получить доступ к входным изменениям.
Пример:
источник
Если в дополнение к автоматической двусторонней привязке вы хотите вызывать функцию при изменении значения, вы можете нарушить синтаксис двусторонней привязки для более подробной версии.
<input [(ngModel)]="yourVar"></input>
это сокращение для
<input [ngModel]="yourVar" (ngModelChange)="yourVar=$event"></input>
(см., например, http://victorsavkin.com/post/119943127151/angular-2-template-syntax )
Вы могли бы сделать что-то вроде этого:
<input [(ngModel)]="yourVar" (ngModelChange)="changedExtraHandler($event)"></input>
источник
Вы можете использовать
getter function
илиget accessor
действовать как часы на угловой 2.Смотрите демо здесь .
источник
Вот еще один подход, использующий функции получения и установки для модели.
источник
(change)
обработчики для каждого из них; Я не хочу добавлятьget|sets
s к каждому свойству в моей модели; это не поможет добавитьget|set
дляthis.object
;ngOnChanges()
обнаруживает только изменения в@Input
с . Святая манна! Что они с нами сделали ??? Верните нам какие-то глубокие часы!Если вы хотите сделать его двухсторонним связыванием, вы можете использовать его
[(yourVar)]
, но вам нужно реализоватьyourVarChange
событие и вызывать его каждый раз, когда меняется ваша переменная.Как то так, чтобы отслеживать смену героя
а потом, когда ваш герой переоденется, позвоните
this.heroChange.emit(this.hero);
[(hero)]
связывании остальное сделает за васпосмотрите пример здесь:
http://plnkr.co/edit/efOGIJ0POh1XQeRZctSx?p=preview
источник
Попробуйте это , когда ваше приложение все еще требует
$parse
,$eval
,$watch
как поведение в угловыхhttps://github.com/vinayk406/angular-expression-parser
источник
Это не дает прямого ответа на вопрос, но я несколько раз сталкивался с этим вопросом переполнения стека, чтобы решить что-то, для чего я бы использовал $ watch в angularJs. Я использовал другой подход, чем описанный в текущих ответах, и хочу поделиться им на случай, если кто-то сочтет это полезным.
Техника, которую я использую для достижения чего-то похожего,
$watch
заключается в использованииBehaviorSubject
( подробнее о теме здесь ) в службе Angular и разрешении моим компонентам подписываться на нее, чтобы получать (наблюдать) изменения. Это похоже на$watch
в angularJs, но требует дополнительной настройки и понимания.В моем компоненте:
В моем сервисе
Вот демо на Stackblitz
источник