Angular: прослушивание модели с помощью ChangeDetectionStrategy.OnPush

Скажем, у меня есть одна большая модель 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?

Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
0
0
47
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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);
      }
    }
}

Другие вопросы по теме