581

*ngForAngular のと*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レベルを上げることですが、 のリスト項目をループするようなシナリオでは、コレクションが空の場合は空になるか、ulが冗長なコンテナー要素にラップされます。lili

このplnkrの例。

コンソール エラーに注意してください。

EXCEPTION: TypeError: Cannot read property 'name' of null in [{{thing.name}} in ShellComponent@5:12]

私は何か間違ったことをしていますか、それともこれはバグですか?

4

17 に答える 17

821

Angular v2 は、同じ要素で複数の構造ディレクティブをサポートしていません。
回避策として、<ng-container>構造ディレクティブごとに個別の要素を使用できるようにする要素を使用しますが、DOM にはスタンプされません

<ng-container *ngIf="show">
  <div *ngFor="let thing of stuff">
    {{log(thing)}}
    <span>{{thing.name}}</span>
  </div>
</ng-container>

<ng-template><template>Angular v4より前)同じことを行うことができますが、構文が異なり、混乱を招き、推奨されなくなりました

<ng-template [ngIf]="show">
  <div *ngFor="let thing of stuff">
    {{log(thing)}}
    <span>{{thing.name}}</span>
  </div>
</ng-template>
于 2016-09-19T05:27:39.663 に答える
97

単一の要素に複数のテンプレート ディレクティブを含めることは angular 1.x で機能しますが、誰もが指摘したように、Angular 2 では許可されていません。詳細については、https ://github.com/angular/angular/issues/ 7315

2016 アンギュラー 2 ベータ版

解決策は、をプレースホルダーとして使用すること<template>です。コードは次のようになります

<template *ngFor="let nav_link of defaultLinks"  >
   <li *ngIf="nav_link.visible">
       .....
   </li>
</template>

ただし、何らかの理由で上記が機能しない2.0.0-rc.4場合は、これを使用できます

<template ngFor let-nav_link [ngForOf]="defaultLinks" >
   <li *ngIf="nav_link.visible">
       .....
   </li> 
</template>

更新された回答 2018

更新により、現在 2018 年の angular v6<ng-container>では、代わりに使用することをお勧めします<template>

だからここに更新された答えがあります。

<ng-container *ngFor="let nav_link of defaultLinks" >
   <li *ngIf="nav_link.visible">
       .....
   </li> 
</ng-container>
于 2016-07-14T16:22:04.137 に答える
6

これは機能しますが、要素は DOM に残ります。

.hidden {
    display: none;
}

<div [class.hidden]="!show" *ngFor="let thing of stuff">
    {{log(thing)}}
    <span>{{thing.name}}</span>
</div>
于 2016-08-15T17:25:22.103 に答える
5

同じ要素にngForとを持つことはできません。できることは、例のトグルがクリックされるまで、ngIf使用している配列への入力を保留することです。ngFor

これを行う基本的な(あまり優れていない)方法は次のとおりです。http://plnkr.co/edit/Pylx5HSWIZ7ahoC7wT6P

于 2016-01-07T14:48:51.857 に答える
3

angular2 ベータ 8 に更新

angular2 ベータ 8 以降、同じコンポーネントで使用できるよう*ngIfになりましたhere を参照してください*ngFor

代わりの:

、 ( ) 、または( ) のようにtr、別の内部で HTML タグを使用できない場合があります。別の HTML タグを使用することはできませんが、同じ状況で何らかのアクションを実行する必要があるため、この方法で HTML5 機能のタグを付けることができます。thtableliul<template>

テンプレートを使用する場合:

<template ngFor #abc [ngForOf]="someArray">
    code here....
</template>

テンプレートを使用するngIf:

<template [ngIf]="show">
    code here....
</template>    

angular2 の構造ディレクティブの詳細については、こちらを参照してください

于 2016-04-04T11:52:02.260 に答える
1
<div *ngFor="let thing of show ? stuff : []">
  {{log(thing)}}
  <span>{{thing.name}}</span>
</div>
于 2018-01-16T10:13:10.570 に答える
0

他の解決策では、表示したくない場合に for ループに空の配列を入れることです。

<div *ngFor="let thing of show ? stuff : []">

「stuff」は「thing」の配列で、「show」はコンテンツを表示するかどうかのブール値です

于 2020-09-02T14:24:54.507 に答える