在将Angular版本升级并把组件改为独立组件后,出现NG0100错误
我对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文档中有说明。
我认为这个错误是由更新子组件输入的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导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。