【问题标题】:Change Detection Strategy onpush not working更改检测策略 onpush 不起作用
【发布时间】:2021-03-06 04:16:52
【问题描述】:

Parent.component.html

<app-child [activeUser]="activeUser"  *ngIf="eceConfirm && activeUser"></app-child>

Parent.component.ts 在 ngOnInit 中,我调用 getAllEmployees 来获取所有员工数据,并使用 @Input() activeUser 将第 0 个索引数据传递给子组件。

 getAllEmployees() {
    this.service
      .getCommonEmployeesDetail(this.user["uid"], this.selectedRatingCycleId)
      .subscribe((res) => {
        this.userList = res;
        this.changeUser(this.userList[0]);
      });
  }

  changeUser(user) {
    console.log("user", user);
    this.activeUser=user;
  }

Child.component.ts

我已经在我的子组件中实现了 changeDetection.Onpush 策略。 获取我的 activeUser 数据后,我将其传递给 changeChildUser() 方法以从请求中获取数据并将其分配给 this.cycleData。

我面临的问题 1.当我尝试在 HTML 页面中打印 {{cycleData.Englishmarks}} 时不会刷新。我安慰了 this.cycleData,它在控制台中显示了值。

任何想法可能是什么问题。任何输入表示赞赏。在此先感谢

 @Input() activeUser: BpuData;

ngOnChanges(changes: SimpleChanges) {
this.changeChildUser();
}



changeChildUser() {
    this.chapterService.getcycle(this.activeUser).subscribe(response =>{
         this.cycleData=response;
});  
      }

【问题讨论】:

  • 使用异步管道。尽量避免使用subscribe,因为您不必记得退订。仅供参考,您这里有内存泄漏。

标签: angular typescript


【解决方案1】:

OnPush 组件的最佳解决方案是使用markForCheck()detectChanges() 也解决了这个问题,但它会产生性能问题,因为它会触发树中的其他组件。

https://angular.io/api/core/ChangeDetectorRef#markForCheck

constructor(private cd: ChangeDetectorRef) {}

this.chapterService.getcycle(this.activeUser).subscribe(response => {
  this.cycleData = response;
  this.cd.markForCheck();
});

我为你的项目准备了一个例子。

https://stackblitz.com/edit/angular-ivy-duuj5y

如果您想确切了解发生了什么,这里有一个很好的解释。

https://stackoverflow.com/a/41364469/6478359

【讨论】:

    【解决方案2】:

    这是因为仅当 OnPush 组件中的输入发生更改时,检测才会更改。

    您必须手动检测更改:

    changeChildUser() {
        this.chapterService.getcycle(this.activeUser).subscribe(response =>{
             this.cycleData=response;
             this.cdr.detectChanges();
        });  
    }
    

    或者你async pipe@Maxime 已经评论了。

    PS:永远记得在销毁时取消订阅。

    【讨论】:

    • 假设我添加了类似的函数,如 changeChildUser()。在每个函数中我可以调用 this.cdr.detectChanges();这是一个好习惯吗?
    • 是的,您可以,我相信这是一个很好的做法,因为它只会检查您需要的子组件中的更改。如果您的子组件中有多个组件,您应该注意性能问题。但请注意,MarkForCheck 不会调用检测。只有当父调用时,您的组件才会被更改。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-04
    • 1970-01-01
    • 2019-08-31
    • 2016-10-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多