同じ要素でAngular の*ngFor
とを使用しようとすると問題が発生します。*ngIf
内のコレクションをループしようとすると*ngFor
、コレクションは として認識されnull
、その結果、テンプレート内でそのプロパティにアクセスしようとすると失敗します。
@Component({
selector: 'shell',
template: `
<h3>Shell</h3><button (click)="toggle()">Toggle!</button>
<div *ngIf="show" *ngFor="let thing of stuff">
{{log(thing)}}
<span>{{thing.name}}</span>
</div>
`
})
export class ShellComponent implements OnInit {
public stuff:any[] = [];
public show:boolean = false;
constructor() {}
ngOnInit() {
this.stuff = [
{ name: 'abc', id: 1 },
{ name: 'huo', id: 2 },
{ name: 'bar', id: 3 },
{ name: 'foo', id: 4 },
{ name: 'thing', id: 5 },
{ name: 'other', id: 6 },
]
}
toggle() {
this.show = !this.show;
}
log(thing) {
console.log(thing);
}
}
簡単な解決策は を*ngIf
1 レベル上に移動することですが、 内のリスト項目をループするようなシナリオでは、コレクションが空の場合は がul
空になるか、 が冗長なコンテナー要素でラップされることになります。li
li
この例plnkr。
コンソールエラーに注意してください:
EXCEPTION: TypeError: Cannot read property 'name' of null in [{{thing.name}} in ShellComponent@5:12]
何か間違っているのでしょうか、それともバグでしょうか?
ベストアンサー1
Angular v2 では、同じ要素に対して複数の構造ディレクティブをサポートしていません。
回避策として<ng-container>
、各構造ディレクティブに個別の要素を使用できる要素を使用しますが、これはDOM にスタンプされません。
<ng-container *ngIf="show">
<div *ngFor="let thing of stuff">
{{log(thing)}}
<span>{{thing.name}}</span>
</div>
</ng-container>
Angular v17以降のアップデート
<ng-container>
Angular v17 で制御フローが導入されて以来、このアプローチは推奨できなくなりました。
@if(show){
@for(thing of stuff; track thing.id){
<div>
{{log(thing)}}
<span>{{thing.name}}</span>
</div>
}
}