ngOnChanges не вызывается, но представление обновляется правильно - PullRequest
0 голосов
/ 04 марта 2020

У меня есть вопрос, связанный со следующим кодом:

Child

export class ChildComponent implements OnChanges {
    public @Input() data: string[];

    ngOnChanges(changes: SimpleChanges) {
        console.log('I am here');
    }
}

Child Template

{{ data | json }} // This is not necessary. The behaviour is the same with or without it.

<div *ngFor="let item of data">
    {{ item }}
</div>

Parent

export class AppComponent implements OnInit {
    public test: string[] = ['hello'];

    ngOnInit() {
        console.log('I am here');
    }

    public addItem() {
        this.test.push('sample');
    }
}

Родительский шаблон

<child-component [data]="test"></child-component>
<button (click)="addItem()">Add</button>

Я понимаю, что ngOnChanges будет вызываться только при изменении ссылки на массив, и если я добавлю sh элемент в массив, он не будет вызван. Следующее привлекает мое внимание. Когда я нажимаю кнопку добавления, новый элемент добавляется в массив, и представление обновляется правильно. Я использую канал json и ngFor, чтобы доказать, что он обновляется правильно. Если я не использую json pipe, поведение будет таким же. Итак, если представление обновлено правильно, почему не вызывается ngOnChanges? Кто несет ответственность за обнаружение изменения, отображающего его в представлении?

Таким образом, сомнение заключается в следующем. Почему при добавлении элемента в массив представление корректно обновляется, но почему не вызывается ngOnChanges?

Обнаружение изменений выполняется по-другому?

1 Ответ

2 голосов
/ 04 марта 2020

Как вы, возможно, знаете, ngOnChanges предназначен для обработки любых изменений в свойствах @Input() (в случае, если простая подача новых данных в компонент может иметь некоторые дополнительные эффекты и не может быть выполнена путем объединения * 1003). * и @Input()). Поэтому он ориентирован только на @Input() изменений. Также, как Вы хорошо знаете, это будет обновляться, только если ссылка собирается измениться.

И Ваш компонент обновляется в любом случае, потому что:

  • Вы не говорите компоненту использовать только OnPush стратегия обнаружения изменений (таким образом, она будет меняться не только при тех эталонных изменениях любого @Input() или любого наблюдаемого / события)
  • и, кроме того (что является ключевым здесь), у вас есть inpure труба внутри вашего ребенка. Здесь я нашел вопрос о грязных каналах и думаю, что он должен ответить на Ваш вопрос: ссылка (так как json труба не работает - документы ). Попробуйте удалить его и посмотрите, что произойдет.

Пожалуйста, примите тот факт, что это всего лишь теория. Но я совершенно уверен, что это правильно.

Редактировать: о, и кажется, что в официальных документах есть прекрасный пример этого здесь :

... летающие герои отображают обновления по мере добавления героев, даже когда вы изменяете массив героев.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...