我的应用程序中有一个简单的组件MenuPageComponent:

...
changeDetection: ChangeDetectionStrategy.OnPush
})
export class MenuPageComponent implements OnInit, OnDestroy {

  private menuService = inject(MenuService); 
  menu: Menu[] = [];
  categories = [
    {id: 1,name: "Food"},
    {id: 2,name: "Bar"}
  ]

 
  // From API 
  constructor() {
    this.menuService.fetch().pipe(
      takeUntilDestroyed()
    ).subscribe(
      response => this.menu = response
    )
  }  
   // Filter - split data by category = bar & food
   getByCategory(categoryId: number) : Menu[] {
    return this.menu.filter((result) => {
      return result.category === categoryId;
    })
  }  

使用html模板(mat-tab键):

enter image description here


 <mat-tab-group color="accent">
  @for (category of categories; track category.id) {
    <mat-tab>
      <ng-template mat-tab-label>{{ category.name }}</ng-template>
  
   @for (menuItem of getByCategory(category.id); track menuItem.id) {

      <ng-container>
          <div>
            <div class="item">
              <div class="title">{{ menuItem.name }}</div>
              <div class="space"></div>
              <div class="price">{{ menuItem.price }}₽</div>
            </div>
            <p class="description">{{ menuItem.description }}</p>
          </div>
        </ng-container>
   }

    </mat-tab>
  }
</mat-tab-group>

当我第一次访问这个页面时,一切都很正常.当我切换到"wine 吧"选项卡时,那里的一切都很好.但当我返回到食物标签时,数据消失了.

enter image description here enter image description here

当我移除changeDetection: ChangeDetectionStrategy.OnPush个时,它工作得很好. 我可以在这个组件上使用"OnPush"吗?(或者这是完全不必要的?)

推荐答案

以下是ChangeDetectionStrategy Docs美元的

OnPush

使用CheckOnce策略,这意味着自动更改检测 停用,直到通过将策略设置为默认而重新激活 (始终选中).仍然可以显式调用更改检测.这 策略适用于所有子指令,不能被重写.

更进一步,我们可以看看Using OnPush Docs

OnPush变化检测指示Angular 运行变化检测 仅在以下情况下才会显示组件子树:

  • The root component of the subtree receives new inpuTS as the result of a template binding. Angular compares the current and past value of the input with ==
  • Angular handles an event (for example using event binding, output binding, or @HostListener ) in the subtree's root component or any of iTS children whether they are using OnPush change detection or not.

So in your scenario, there is no change of 100 nor hostlisteners being triggered in your code, so change detection has not detected the changes

何时使用更改检测策略-推送

  1. 当设置正常更改检测时,组件的性能受到影响,这可能是由于大量侦听器或与更改检测相关的繁重前端代码.
  2. When you are sure that the component is pretty basic and all scenarios can be handled without the full fledged change detection, meaning that same can be achieved by on push iTSelf ( Better overall application performance, since few componenTS wont have change detection which increases memory of browser for more important tasks! )

How to trigger manual Change detection - Change Detector Ref Docs

我们可以导入更改检测器引用并调用方法.


因此,您的问题的修复方法可能是使用markForCheck()detectChanges()手动触发更改检测.由于我们希望对选项卡更改运行更改检测,因此我们使用MAT选项卡事件selectedTabChange

TS

...
constructor(
    ...
    private cdr: ChangeDetectorRef,
    ...) {}

selectedTabChange() {
    this.cdr.detectChanges();
    // or
    // this.cdr.markForCheck();
}

HTML

...
<mat-tab-group color="accent" (selectedTabChange)="selectedTabChange($event)">
    ...

Angular相关问答推荐

尾风手风琴中的Ngor

Change上的Angular 自定义控件无法正常工作

TransLoco合并本地和服务器端转换对象

Angular 17:延迟加载带参数的独立组件?

我应该对我想要在我的Angular 17+组件中显示的任何变量使用信号吗?

Angular react 形式验证问题

如何从2个api获取数据并查看Angular material 表中的数据?

NgRx Effects 抛出类型错误,我不知道发生了什么

nx workspace angular monorepo 在创建新应用程序时抛出错误

手动关闭 SSE 连接:Angular

将 html ngModel 值传递给服务 --Angular

*ngIf 和 *ngFor 在 元素上使用

为什么 Angular2 routerLinkActive 将活动类设置为多个链接?

Angular 2 应用程序中没有Access-Control-Allow-Origin标头

Angular 2:formGroup 需要一个 FormGroup 实例

安装特定版本的 ng cli

Angular2中是否有像window.onbeforeunload这样的生命周期钩子?

没有 ChildrenOutletContexts 的提供者 (injectionError)

'Observable' 类型上不存在属性 'filter'

路由 getCurrentNavigation 始终返回 null