#angular #rxjs #angular2-changedetection
#angular #rxjs #angular2-измененное обнаружение
Вопрос:
Допустим, у меня есть одна большая модель Json, которую мой сервер отправляет моему интерфейсу, которая будет выглядеть следующим образом:
{
dataA: { //some object },
dataB: { //some object },
dataC: { //some object },
...
}
Теперь допустим, у меня есть компонент, который принимает dataA как @Input()
, компонент B, который принимает dataB как @Input()
и т. Д:
@Component({
selector: 'comp-a'
})
class ComponentA {
@Input() _dataA;
}
@Component({
selector: 'comp-b'
})
class ComponentA {
@Input() _dataB;
}
// .... other components
@Component({
selector: 'app',
template:`
<comp-a [_dataA]="dataA"></comp-a>
<comp-b [_dataB]="dataB"></comp-b>
...
`
})
class AppComponent {
}
И что я хочу заставить эти компоненты использовать стратегию обнаружения изменений OnPush.
При получении новой модели может случиться так, что поле данных в модели не изменилось по сравнению с его предыдущим значением в предыдущей модели, поэтому я бы не хотел, чтобы они снова передавались как @Input()
компоненту, чтобы избежать запуска обнаружения изменений впустую.
Есть ли какой-нибудь умный способ обнаружить изменения в моей модели на интерфейсной стороне, прежде чем передавать ее данные как @Input()
моим компонентам, и уведомлять их только тогда, когда их соответствующие данные изменились? Или я должен позволить Angular выполнять само обнаружение изменений? Действительно ли OnPush здесь уместен?
Ответ №1:
OnPush повышает эффективность, поскольку не проверяет свойства модели и запускает обновление при изменении экземпляра объекта, а не свойств объекта. Для выполнения того, что вы предлагаете, потребуется проверить свойства вашего объекта, чтобы увидеть, изменилось ли что-нибудь. По сути, вы бы заново изобрели обнаружение изменений, поэтому я не вижу в этом смысла, и вам нужно было бы сделать это лучше, чем это сделала команда Angular, чтобы увидеть какую-либо выгоду.
Вы также отметили этот вопрос с помощью rxjs, но в вопросе ничего нет о rxjs. Лучший способ реализовать обнаружение изменений OnPush — это использовать rxjs observables и использовать асинхронный канал в вашем шаблоне. Таким образом, вы получаете только наблюдаемое, которое выдает обновленное значение.
@Component({
selector: 'app',
template:`
<comp-a [_dataA]="dataA$ | async"></comp-a>
<comp-b [_dataB]="dataB$ | async"></comp-b>
...
`
})
class AppComponent {
dataA$ = new BehaviorSubject<DataAModel>(undefined);
dataB$ = new BehaviorSubject<DataBModel>(undefined);
updateA() {
if (a has changed) { // If your detection to check changes is inefficient then there is no point
this.dataA$.next(a);
}
}
updateB() {
if (b has changed) {
this.dataB$.next(b);
}
}
}