【发布时间】:2021-09-15 16:41:13
【问题描述】:
在我的场景中,我有一个父组件在按钮单击时接收新数据。子组件通过@Input 字段接收这些数据。在子组件事件ngOnChanges 被触发。 isLoaded 字段的值按预期更新。问题是:为什么我的 HTML 条件 <div *ngIf="isLoaded"> 需要 this.cd.detectChanges() 才能注意到 isLoaded 标志已更改?
父组件:
@Component()
export class ParentComponent implements OnInit {
data: MyData;
ngOnInit(): void {
}
updateWhenClickButton() {
this.someService.getData(this.a, this.b, this.c).then(dataabc =>{
this.data = new PurchasePriceBoxPlotData(this.a, this.b, dataabc);
});
}
}
父 HTML 内容:
<child-component [data]="data"></child-component>
子组件:
@Component()
export class ChildComponent implements OnInit, OnChanges {
@Input()
data: MyData;
isLoaded: boolean = false;
constructor(private cd: ChangeDetectorRef) { }
ngOnInit(): void {
this.doSth();
}
ngOnChanges(changes: SimpleChanges): void {
this.isLoaded = false;
this.cd.detectChanges();
this.doSth();
}
private doSth() {
....
this.isLoaded = true;
}
}
子 HTML:
<div *ngIf="isLoaded">
<custom-component [data]="data"></custom-component>
</div>
编辑
public isLoaded$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
ngOnChanges(changes: SimpleChanges): void {
this.isLoaded$.next(false);
this.dosth();
this.isLoaded$.next(true);
}
<div *ngIf="isLoaded$ | async">
【问题讨论】:
-
能给个stackblitz示例代码吗?
-
你真的不应该正常使用 - 你在链上的某个地方使用 onPush 吗?另外 - 你在这里做了一些奇怪的事情。为什么从 onChanges 调用 ngOninit 以及为什么假设 onChanges 触发加载时为假?
-
@MikeOne 1. 我没有使用 onPush。 2. ngOninit 只是因为我想在每次出现新数据时重新创建子组件。这可能不是最好的主意,因为在创建组件时应该调用一次 oninit。也许我应该只更新在 onInit 期间创建的设置,而不是每次都从头开始创建它们。 3. 就像我在#2 中所说的那样。这个标志让我用更新的数据/设置重新创建子组件。是的,我知道这可能不是最佳方式,但我只是在学习 Angular 并寻求改进。
-
默认情况下更改检测发生在
ngOnChanges的末尾,不是吗?
标签: angular