изменение обнаружения в угловых является огромной темой. Здесь у вас есть очень вложенный объект, где угловые должны отслеживать, чтобы обнаружить изменения.
Для этого угла нет возможности рекурсивно проверять каждое поле вашего объекта и сравнивать его с предыдущим состоянием, чтобы определить, есть ли у вас какие-либо изменения. Этот шаг вызывает дайджест и помечает как грязный. Это очень трудоемкий процесс, поэтому angular делает это в особом случае (список не полный, просто для демонстрации):
- @ Выход триггерный
- @ Ввод изменен
- отправляется событие браузера (щелчок, зависание и т. Д.)
- таймаут
- интервал
- ....
здесь вы изменяете свой объект, вызывая функцию из атрибута [disable] html. Я подозреваю, что этот случай не распространяется на changeDetectionStrategy по умолчанию.
В любом случае угловая команда не рекомендует манипулировать таким объектом. Рекомендуется использовать любой из этих двух подходов:
- Избегайте изменения состояния, предпочитайте создавать новый объект и заменять предыдущий. Как этот простой угол должен сделать myPreviousObject !== myNewObject
вместо:
if (
myPreviousObject.prop1 !== myNewObject.prop1 ||
myPreviousObject.prop2 !== myPreviousObject.prop2 ||
....
)
- Использовать Observable с неизменным состоянием.
для моей демонстрации я использовал второй подход, и здесь вы можете найти простую реализацию:
моя модель:
export interface disableState {
PURCHASE_LIEN: {
disable: boolean;
disable$: BehaviorSubject<boolean>
};
NOT_QUALIFIED: {
disable: boolean;
disable$: BehaviorSubject<boolean>
};
}
внутри моего компонента у меня есть такое свойство:
disableState: disableState = {
NOT_QUALIFIED: {
disable: false,
disable$: new BehaviorSubject<boolean>(false),
},
PURCHASE_LIEN: {
disable: false,
disable$: new BehaviorSubject<boolean>(false),
},
}
и когда я хочу изменить это значение, я могу сделать это так:
/**
* Call your service like :
* this.validation.disableButton()
*/
this.disableState['NOT_QUALIFIED'].disable = true;
this.disableState['NOT_QUALIFIED'].disable$.next(true);
живое кодирование
Полный компонент:
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class AppComponent {
disableState: disableState = {
NOT_QUALIFIED: {
disable: false,
disable$: new BehaviorSubject<boolean>(false),
},
PURCHASE_LIEN: {
disable: false,
disable$: new BehaviorSubject<boolean>(false),
},
}
showModal(id: string) {
console.log(`Open modal : ${id}`);
}
dummyPropertyChange() {
/**
* Call your service like :
* this.validation.disableButton()
*/
this.disableState['NOT_QUALIFIED'].disable = true;
this.disableState['NOT_QUALIFIED'].disable$.next(true);
}
}
Обратите внимание, что у меня есть переключатель ChangeDetectionStrategy
, чтобы запросить angular только для грязной проверки путем простого сравнения объектов (вместо вложенной). С этого момента, если я хочу обновить данные, я должен:
- изменить данные всей переменной (вместо только вложенного свойства)
- использовать наблюдаемый для выполнения изменений на временной шкале.