Что такое угловой эквивалент AngularJS $watch?
в AngularJS вы смогли указать наблюдателей для наблюдения за изменениями переменных области с помощью на $scope
. Каков эквивалент наблюдения за переменными изменениями (например, в компонентных переменных) в Angular?
7 ответов:
в угловом 2, обнаружение изменения автоматическое...
$scope.$watch()
и$scope.$digest()
Р. И. П.к сожалению, раздел обнаружения изменений руководства dev еще не написан (есть заполнитель в нижней части Обзор Архитектуры страница, в разделе "остальное").
вот мое понимание того, как работает обнаружение изменений:
- зоны.js "monkey patches the world" -- он перехватывает все асинхронные API в браузер (когда угловой работает). Вот почему мы можем использовать
setTimeout()
внутри нашего компонентов, а не что-то вроде$timeout
... потому чтоsetTimeout()
это патченные.- Angular строит и поддерживает дерево "детекторов изменений". Существует один такой детектор изменений (класс) на компонент/директиву. (Вы можете получить доступ к этому объекту, введя
ChangeDetectorRef
.) Эти детекторы изменения создаются, когда угловой создает компоненты. Они отслеживают состояние всех ваши привязки, для грязной проверки. Это, в некотором смысле, похожи на автоматические$watches()
что угловой 1 будет настроен на{{}}
привязки шаблона.
в отличие от углового 1, граф обнаружения изменений является ориентированным деревом и не может иметь циклов (это делает угловой 2 гораздо более производительным, как мы увидим ниже).- когда событие срабатывает (внутри угловой зоны), выполняется код, который мы написали (обратный вызов обработчика событий). Он может обновлять любые данные, которые он хочет -- общее приложение модель / состояние и / или состояние представления компонента.
- после этого, из-за пояса крючки.JS добавил, затем он запускает алгоритм обнаружения изменений Angular. По умолчанию (т. е. если вы не используете
onPush
изменить стратегию обнаружения на любом из ваших компонентов), каждый компонент в дереве рассматривается один раз (TTL=1)... сверху, в глубину-первый порядок. (Ну, если вы находитесь в режиме dev, обнаружение изменений выполняется дважды (TTL=2). Смотрите ApplicationRef.ТИК() подробнее об этом.) Он выполняет грязную проверку всех ваших Привязок, используя эти объекты детектора изменений.
- крючки жизненного цикла вызываются как часть обнаружения изменений.
если данные компонента, которые вы хотите просмотреть, являются примитивным свойством ввода (String, boolean, number), вы можете реализоватьngOnChanges()
для уведомления об изменениях.
если входное свойство является ссылочным типом (объект, массив и т. д.), но ссылка не изменилась (например, вы добавили элемент в существующий массив), вам нужно будет реализоватьngDoCheck()
(см. это так ответ подробнее об этом).
вы должны изменить только свойства компонента и / или свойства компонентов-потомков (из-за реализации одиночного дерева-т. е. однонаправленного потока данных). Вот это в plunker, что нарушает это. Статусные трубы также могут тебе подножку здесь.- для каких-либо обязательных изменений, которые будут найдены, то компоненты будут обновлены, а затем DOM обновляется. Обнаружение изменений теперь завершено.
- браузер замечает изменения DOM и обновляет экран.
другие ссылки, чтобы узнать больше:
- Angular $digest возрождается в новой версии Angular - объясняет, как идеи из AngularJS отображаются на Angular
- все, что вам нужно знать об обнаружении изменений в Angular - объясняет очень подробно, как обнаружение изменений работает под капотом
- Обнаружение Изменений Объяснил - блог Thoughtram 22 февраля 2016 года-вероятно, лучшая ссылка там
Савкина!--68-->Обнаружение Изменений Заново видео-определенно смотреть этот- как на самом деле работает обнаружение угловых изменений 2?- блог jhade 24 февраля 2016
- Брайан видео!--16--> и видео Мишко о зоне.js. Брайан-это о зоне.js. Мишко о том, как угловой 2 использует зону.JS для реализации обнаружения изменений. Он также говорит об обнаружении изменений в целом, и немного о
onPush
.- Виктор Савкинс сообщения в блоге:обнаружение изменения в угловом 2, две фазы угловых приложений 2,угловой, неизменяемость и инкапсуляция. Он быстро покрывает много земли, но иногда он может быть немногословным, и вы оставляете почесывать голову, размышляя о недостающих частях.
- Ультра Быстрое Обнаружение Изменений (Google doc) - очень технический, очень краткий, но он описывает/эскизы классов ChangeDetection, которые строятся как часть дерева
такое поведение теперь является частью жизненного цикла компонента.
компонент может реализовать метод ngOnChanges в OnChanges интерфейс для получения доступа к изменениям ввода.
пример:
import {Component, Input, OnChanges} from 'angular2/core'; @Component({ selector: 'hero-comp', templateUrl: 'app/components/hero-comp/hero-comp.html', styleUrls: ['app/components/hero-comp/hero-comp.css'], providers: [], directives: [], pipes: [], inputs:['hero', 'real'] }) export class HeroComp implements OnChanges{ @Input() hero:Hero; @Input() real:string; constructor() { } ngOnChanges(changes) { console.log(changes); } }
Если в дополнение к автоматической двусторонней привязке вы хотите вызвать функцию при изменении значения, вы можете разбить синтаксис ярлыка двусторонней привязки на более подробную версию.
<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.посмотреть демо здесь.
import {Component} from 'angular2/core'; @Component({ // Declare the tag name in index.html to where the component attaches selector: 'hello-world', // Location of the template for this component template: ` <button (click)="OnPushArray1()">Push 1</button> <div> I'm array 1 {{ array1 | json }} </div> <button (click)="OnPushArray2()">Push 2</button> <div> I'm array 2 {{ array2 | json }} </div> I'm concatenated {{ concatenatedArray | json }} <div> I'm length of two arrays {{ arrayLength | json }} </div> ` }) export class HelloWorld { array1: any[] = []; array2: any[] = []; get concatenatedArray(): any[] { return this.array1.concat(this.array2); } get arrayLength(): number { return this.concatenatedArray.length; } OnPushArray1() { this.array1.push(this.array1.length); } OnPushArray2() { this.array2.push(this.array2.length); } }
вот еще один подход, использующий функции getter и setter для модели.
@Component({ selector: 'input-language', template: ` … <input type="text" placeholder="Language" [(ngModel)]="query" /> `, }) export class InputLanguageComponent { set query(value) { this._query = value; console.log('query set to :', value) } get query() { return this._query; } }
если вы хотите сделать ее 2 способ привязки, вы можете использовать
[(yourVar)]
, но вы должны реализоватьyourVarChange
событие и вызвать его каждый раз, когда переменная меняется.что-то вроде этого, чтобы отслеживать изменение героя
@Output() heroChange = new EventEmitter();
а потом, когда ваш герой переоденется, позвоните
this.heroChange.emit(this.hero);
the
[(hero)]
привязка сделает все остальное за вассм. пример здесь: