Я прочитал, что Угловое обнаружение 2 изменения ... становится стабильным после одного прохода
Угловые 2 не «получить стабильные». С приложениями Angular 2 мы отвечаем за то, что мы пишем наше приложение таким образом, чтобы оно всегда было стабильным после одного прохода.
По умолчанию (например, вы не используете стратегию обнаружения OnPush
изменений на каких-либо компоненты, не так ли detach() какие-либо компоненты), обнаружение изменений работает следующим образом:
- Zone.js обезьяньей заплатой асинхронного события – например, событие
(click)
, ответ XHR, таймер setTimeout()
. Выполняется обратный вызов, связанный с этим событием, который может изменить любой вид или данные приложения в нашем приложении. Затем, из-за обезьяны-патча, происходит обнаружение углового изменения. Другими словами, по умолчанию (например, вы не являетесь manually triggering change detection), только обнаружение изменений асинхронных событий, связанных с обезьяной, вызывает обнаружение изменений.
- Начиная с корневого компонента и прохода вниз по дереву компонентов (обход по глубине), каждая привязка данных проверяется на изменение. Если обнаружено изменение, это изменение «распространяется».В зависимости от типа связывания с шаблоном распространение может
- распространять измененное значение в DOM. Например, когда используется привязка
{{}}
, новое значение распространяется на свойство textContent
соответствующего элемента DOM.
- распространять измененное значение на дочерний компонент. Например, при использовании привязки входных свойств (
[childInputProperty]="parentProperty"
) новое значение распространяется на свойство дочернего ввода.
- Если вы находитесь в режиме разработчика, все компоненты загрязнены проверены еще раз, но нет распространения не происходит. Эта вторая грязная проверка помогает нам найти проблемы с нашим кодом, например, если мы нарушили idempotent rule, что является причудливым способом сказать, что одно из наших привязок (его выражение в шаблоне) имеет побочные эффекты. Другими словами, дополнительные проверки режима Dev сообщают нам, если наш код нестабилен после одного прохода.
Побочные эффекты не допускаются в Угловом 2. В связи с вашим вопросом дочерний компонент поэтому не должен изменять родительское свойство в результате распространения свойства ввода. Итак, вы могли бы сказать, что Angular 2 «разрешает» ситуацию, о которой вы просили, не разрешая ее.
Это не так плохо, как может показаться. Единственный способ, которым я знаю, что распространение входного свойства может изменить родительское свойство, - это если дочерний компонент реализует метод setter для свойства ввода, который модифицирует другое свойство, которое родительский отображает в своем шаблоне. (Вот old plunker, который делает это - см. Метод @Input set backdoor()
.) Обычно вы не сделали бы этого. Если вам нужно это сделать, тогда комментарий Гюнтера будет выглядеть следующим образом: сделайте изменение внутри setTimeout()
, поэтому оно станет частью следующего цикла обнаружения изменений.
Я хочу еще раз подчеркнуть: обработчики событий запускаются до обнаружения изменений, поэтому они могут свободно изменять любые данные в нашем приложении. - данные локального/компонентного представления, данные приложения, что угодно. Поэтому в обработчике событий дочерний компонент может изменять родительские данные. Например, предположим, что родительский и дочерний объекты имеют ссылку на один и тот же массив. Когда обработчик события запускается, родительский и/или дочерний компоненты могут изменять этот массив.
Так что если вы вносите изменения в обработчики событий, никаких проблем. Существует только проблема, если ваш сеттер делает что-то странное.
Спасибо за подробное объяснение. Это помогло мне лучше понять механизм обнаружения изменений. Приветствия. – Fjut
Вы можете просто использовать 'setTimeout (changeParentHere)', если это действительно то, что вы хотите. –