*ngIf と *ngFor が同じ要素にあるとエラーが発生する 質問する

*ngIf と *ngFor が同じ要素にあるとエラーが発生する 質問する

同じ要素で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);
  }

}

簡単な解決策は を*ngIf1 レベル上に移動することですが、 内のリスト項目をループするようなシナリオでは、コレクションが空の場合は がul空になるか、 が冗長なコンテナー要素でラップされることになります。lili

この例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>
 }
}

おすすめ記事