Ответ 1
Хороший вопрос. У меня есть две цитаты из Савкина оonPush
(так как у Angular.io docs пока нет информации по этой теме):
Структура будет проверять компоненты
onPush
только при изменении их входов или создании шаблонов компонентов. - refПри использовании
onPush
, Angular будет проверять компонент только тогда, когда какое-либо из его свойств ввода изменяется, когда оно запускает событие или когда наблюдаемый запускает событие. - ref (в ответе на комментарий к @vivainio)
Вторая цитата кажется более полной. (Слишком плохо, что он был похоронен в комментарии!)
Почему назначение нового строкового значения
Success!
не запускает датчик изменения? Что касается неизменности, значение изменилось, правильно?
onPush
неизменяемость относится к свойствам ввода, а не к нормальным свойствам экземпляра. Если loadingMessage
было входным свойством и значение изменилось, обнаружение изменений будет выполняться на компоненте. (См. Ответ @Vlado для Plunker.)
Как должно быть реализовано легкое внутреннее состояние компонента (т.е.
loadingMessage
) при использованииChangeDetectionStrategy.OnPush
? Если есть несколько лучших практик, пожалуйста, укажите мне в правильном направлении.
Вот что я знаю до сих пор:
- Если мы изменим внутреннее состояние как часть обработки события или часть наблюдаемого срабатывания, обнаружение изменения выполняется в компоненте
onPush
(т.е. представление будет обновляться). В вашем конкретном случае я был удивлен, что представление не обновлялось. Вот два догадки о том, почему нет:- Добавление
delay()
делает Angular более похожим наsetTimeout()
, чем на наблюдаемое изменение.setTimeout
не приводят к выполнению обнаружения изменений в компонентеonPush
. В вашем примере детектор изменений завершил свою работу за 2 секунды до изменения значенияloadingMessage
. - Как @Sasxa показывает в своем ответе, вы должны иметь привязку в шаблоне к
Observable
. Я., возможно, это больше, чем просто "наблюдаемые огни"... возможно, это должно быть наблюдаемое связанное, которое срабатывает. В этом случае созданиеloadingMessage
(или даже более общее свойствоstate
) в качестве самогоObservable
позволит вам привязать ваш шаблон к его значению (или нескольким значениям асинхронности), см. этот пример plnkr.
Обновление 2016-04-28: Кажется, что привязка должна включать| async
, как показано в plnkr, и в this plnkr.
- Добавление
- Если мы изменим внутреннее состояние и не являемся частью обработки событий или наблюдаемого обжига, мы можем ввести
ChangeDetectorRef
в наш компонент и метод вызоваmarkForCheck()
, чтобы вызвать обнаружение изменений для компонентаonPush
и все компоненты предка до корневого компонента. Если изменяется только состояние просмотра (то есть состояние, которое является локальным для компонента и, возможно, его потомков), вместо него может использоватьсяdetectChanges()
, который не будет отмечать все компоненты-предки для обнаружения изменений. Plunker