在将Angular版本升级并把组件改为独立组件后,出现NG0100错误

前端开发 2026-07-11

我对Angular还算是新手,读了文档,但不太明白为什么在我的场景中会出现这种行为。我把我的组件简化成如下:

父组件HTML:

<my-component [data]="data"></my-component>
<br>
<button (click)="getData()">
    Get data
</button>

TypeScript:

export class ParentComponent implements OnInit {
  protected data: MyItem[] = []
  constructor(private apiService: ApiService) {}

  ngOnInit(): void {}

  getData() {
    this.apiService.getData().subscribe((data) => {
      this.data = data
    })
  }
}

如果我这么做,点击按钮时会得到NG0100。

不过,如果把 getData 改成:

getData() {
    this.data =[{item1: 'foobar'}]
}

点击后就不会再报错。

我已经用这种方式解决了这个问题:

@if (data.length > 0) {
    <my-component [data]="data"></my-component>
}
<br>
<button (click)="getData()">
    Get data
</button>

getData

getData(): Observable<MyItem[]> { return this.http.get<MyItem[]>(this.baseUrl) }

其中 this.http 是来自 @angular/common/http 的一个 HttpClient

MyComponent(尽量简化到极致):

<mat-table matSort [dataSource]="data"  class="mat-elevation-z8 col-12">
    <ng-container matColumnDef="nom">
        <mat-header-cell class="col-4" *matHeaderCellDef mat-sort-header disableClear>Description</mat-header-cell>
        <mat-cell class="col-4" *matCellDef="let item">{{item.nom}}</mat-cell> 
    </ng-container>
    <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
    <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
</mat-table>
import { Component, Input } from '@angular/core'
import { Carrec } from '../../../models/carrec.model'
import { MATERIAL_IMPORTS } from '../../material.imports'

@Component({
  selector: 'my-component',
  imports: [MATERIAL_IMPORTS],
  templateUrl: './my-component.component.html',
  styleUrl: './my-component.component.css',
  standalone: true,
})
export class MyComponent {
  @Input()
  data: Carrec[] = []

  displayedColumns: string[] = ['nom']
}

但我不明白为什么在subscribe内修改值会在第一次点击按钮时触发NG0100错误。

在我应用的一个较旧版本中,使用非独立组件时,我都是这样做的,且并没有出现这个错误。

你能不能告诉我在Angular中正确的做法是什么?

解决方案

错误的细节在Angular文档中有说明。

NG0100: 表达式在检查后改变

我认为这个错误是由更新子组件输入的API调用引起的,进而更新mat-table。表格组件是在变更检测已经运行之后才被修改。

一个简单的变通办法是在表格数据发生变化时,调用 this.cdr.detectChanges() 重新运行变更检测。

export class ParentComponent implements OnInit {
  protected data: MyItem[] = []
  constructor(private apiService: ApiService, private cdr: ChangeDetectorRef) {}

  ngOnInit(): void {}

  getData() {
    this.apiService.getData().subscribe((data) => {
      this.data = data;
      this.cdr.detectChanges(); // <- changed here!
    })
  }
}
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章