Скажем, у меня есть одна большая модель Json, которую мой сервер отправляет на мой интерфейс, которая будет выглядеть так:
{
dataA: { //some object },
dataB: { //some object },
dataC: { //some object },
...
}
Теперь предположим, что у меня есть ComponentA, который принимает данные A как @Input(), ComponentB, который принимает данные B как @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?





OnPush повышает эффективность, не проверяя свойства модели, и инициирует обновление при изменении экземпляра объекта, а не свойств объекта. Чтобы сделать то, что вы предлагаете, потребуется проверить свойства вашего объекта, чтобы увидеть, не изменилось ли что-нибудь. По сути, вы будете заново изобретать обнаружение изменений, поэтому я не вижу смысла, и вам нужно будет сделать это лучше, чем команда Angular, чтобы увидеть какую-либо выгоду.
Вы также отметили этот вопрос с помощью rxjs, но в вопросе ничего не говорится о rxjs. Лучший способ реализовать обнаружение изменений OnPush — использовать наблюдаемые объекты rxjs и использовать асинхронный канал в своем шаблоне. Таким образом, вы получаете наблюдаемое только для испускания обновленного значения.
@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);
}
}
}