Я пытаюсь полностью понять обнаружение изменений с помощью Angular2 final.
Это включает:
- Работа со стратегиями обнаружения изменений
- Присоединение и отсоединение детектора изменений от компонента.
Я думал, что уже получил довольно четкий обзор этих концепций, но чтобы убедиться, что мои предположения верны, я написал небольшой plunkr для их проверки.
Мое общее представление об этом в целом правильное, но в некоторых ситуациях я немного теряюсь.
А вот и плункер: Angular2 Change detection Детская площадка
Краткое описание плункера:
Довольно просто:
- Один родительский компонент, в котором вы можете редактировать один атрибут, который будет передан двум дочерним компонентам:
- На дочернем элементе со стратегией обнаружения изменений, установленной на OnPush
- На дочернем элементе со стратегией обнаружения изменений, установленной по умолчанию
Родительский атрибут может быть передан дочерним компонентам одним из следующих способов:
- Изменение всего объекта атрибута и создание нового (кнопка «Изменить объект») (которая запускает обнаружение изменений в дочернем элементе OnPush)
- Изменение членов внутри объекта атрибута (кнопка «Изменить содержимое») (которые не запускают обнаружение изменений в дочернем элементе OnPush)
К каждому дочернему компоненту можно прикрепить или отсоединить ChangeDetector. (кнопки "отсоединить ()" и "повторно прикрепить ()")
У дочернего элемента OnPush есть дополнительное внутреннее свойство, которое можно редактировать, и обнаружение изменений может быть применено явным образом (кнопка «detectChanges ()»).
Вот сценарии, при которых у меня появляется поведение, которое я не могу объяснить:
Сценарий 1:
- Отключить детектор изменений дочерних элементов OnPush и дочерних элементов по умолчанию (нажмите «отсоединить ()» на обоих компонентах)
- Отредактируйте родительский атрибут firstname и lastname
- Нажмите «Изменить объект», чтобы передать измененный атрибут дочерним элементам.
Ожидаемое поведение: я ожидаю, что ОБА дочерних элементов НЕ будут обновлены, потому что у них обоих отключен детектор изменений.
Текущее поведение: дочерний элемент по умолчанию не обновляется, но дочерний элемент OnPush обновляется. ПОЧЕМУ? Не следует, потому что его компакт-диск отсоединен ...
Сценарий 2:
- Отсоедините компакт-диск для компонента OnPush
- Измените его входное внутреннее значение и нажмите изменить внутреннее: ничего не происходит, потому что компакт-диск отсоединен, поэтому изменение не обнаружено ... ОК
- Нажмите detectChanges (): изменения будут обнаружены, и представление обновится. Все идет нормально.
- Еще раз отредактируйте ввод внутреннее значение и нажмите изменить внутреннее: снова ничего не происходит, потому что компакт-диск отсоединен, поэтому изменение не обнаружено .. ОК
- Отредактируйте родительский атрибут firstname и lastname.
- Нажмите «Изменить объект», чтобы передать измененный атрибут дочерним элементам.
Ожидаемое поведение: дочерние элементы OnPush НЕ должны обновляться ВООБЩЕ, потому что их компакт-диск отсоединен ... Компакт-диск не должен происходить в этом компоненте.
Текущее поведение: и значение, и внутренние значения обновляются, на этот компонент накладываются швы, как на полном компакт-диске.
- В последний раз отредактируйте ввод внутреннее значение и нажмите изменить внутреннее: изменение обнаружено, и внутреннее значение обновлено ...
Ожидаемое поведение: внутреннее значение НЕ следует обновлять, поскольку компакт-диск все еще отсоединен.
Текущее поведение: Обнаружено изменение внутреннего значения ... ПОЧЕМУ?
Выводы:
По результатам этих тестов я пришел к следующему выводу, который мне кажется странным:
- Компонент со стратегией OnPush получает «обнаружено изменение» при изменении ввода, ДАЖЕ, ЕСЛИ их детектор изменений отключен.
- Компонент со стратегией OnPush повторно подключает свой детектор изменений каждый раз, когда их ввод изменяется ...
Что вы думаете об этих выводах?
Можете ли вы лучше объяснить такое поведение?
Это ошибка или желаемое поведение?
detach()
отключает детектор изменений для детей, но не сам компонент. Я сам еще не углублялся в обнаружение изменений. - person Günter Zöchbauer   schedule 30.10.2016