web-dev-qa-db-ja.com

Angular 8で@ViewChildの新しい静的オプションを使用するにはどうすればよいですか?

新しいAngular 8ビューの子を構成するにはどうすればよいですか?

@ViewChild('searchText', {read: ElementRef, static: false})
public searchTextInput: ElementRef;

@ViewChild('searchText', {read: ElementRef, static: true})
public searchTextInput: ElementRef;

どちらが良いですか? static:truestatic:falseはいつ使用する必要がありますか?

166
Patrik Laszlo

ほとんどの場合、{static: false}を使用します。このように設定すると、バインディングの解決に依存するクエリの一致(構造ディレクティブ*ngIf, etc...など)が確実に検出されます。

static: falseを使用する場合の例:

@Component({
  template: `
    <div *ngIf="showMe" #viewMe>Am I here?</div>
    <button (click)="showMe = !showMe"></button>
  ` 
})
export class ExampleComponent {
  @ViewChild('viewMe', { static: false })
  viewMe?: ElementRef<HTMLElement>; 

  showMe = false;
}

static: falseは、Angular 9.のデフォルトのフォールバック動作になります。続きを読む here および here

{ static: true }オプションは、埋め込みビューの即時作成をサポートするために導入されました。ビューを動的に作成し、TemplateRefにアクセスする場合、ngAfterViewInitエラーが発生するため、ExpressionHasChangedAfterCheckedでアクセスすることはできません。静的フラグをtrueに設定すると、ngOnInitでビューが作成されます。

それにもかかわらず:

他のほとんどの場合、ベストプラクティスは{static: false}を使用することです。

ただし、{ static: false }オプションは、Angular 9.でデフォルトになります。つまり、static: trueオプション。

angular cli ng updateコマンドを使用して、現在のコードベースを自動的にアップグレードできます。

移行ガイドおよびこれに関する詳細については、 here および here

静的クエリと動的クエリの違いは何ですか?

@ViewChild()および@ContentChild()クエリの静的オプションは、クエリ結果がいつ利用可能になるかを決定します。

静的クエリ(静的:true)では、ビューが作成された後、変更検出が実行される前にクエリが解決されます。ただし、ngIfブロックやngForブロックの変更など、ビューの変更を反映するために結果が更新されることはありません。

動的クエリ(静的:false)を使用すると、@ ViewChild()および@ContentChild()に対してそれぞれngAfterViewInit()またはngAfterContentInit()の後にクエリが解決されます。結果は、ngIfおよびngForブロックの変更など、ビューの変更に対して更新されます。

184
PierreDuc

したがって、経験則として、次のことを実行できます。

  • { static: true }は、ViewChild内のngOnInitにアクセスするときに設定する必要があります。

  • { static: false }ngAfterViewInitでのみアクセスできます。また、これは、構造的なディレクティブがある場合(つまり、*ngIf)テンプレートの要素に。

65
dave0688

angular docs

static-変更検出の実行前にクエリ結果を解決するかどうか(つまり、静的な結果のみを返す)。このオプションが提供されない場合、コンパイラはデフォルトの動作に戻ります。つまり、クエリ結果を使用してクエリ解決のタイミングを決定します。クエリの結果がネストされたビュー(* ngIfなど)内にある場合、クエリは変更検出の実行後に解決されます。それ以外の場合、変更検出が実行される前に解決されます。

子が条件に依存しない場合は、static:trueを使用することをお勧めします。要素の可視性が変更された場合、static:falseはより良い結果をもたらす可能性があります。

PS:新しい機能なので、パフォーマンスのベンチマークを実行する必要があるかもしれません。

編集

@Massimiliano Sartorettoが述べたように、 github commit はより多くの洞察を与えるかもしれません。

17
Sachin Gupta

子の@angular 5+トークン2つの引数を表示( 'local reference name'、static:false | true)

@ViewChild('nameInput', { static: false }) nameInputRef: ElementRef;

真と偽の違いを知るには、これをチェックしてください

static-変更検出を実行する前にクエリ結果を解決するかどうか(つまり、静的な結果のみを返す)。このオプションが提供されない場合、コンパイラはデフォルトの動作に戻ります。つまり、クエリ結果を使用してクエリ解決のタイミングを決定します。クエリの結果がネストされたビュー(* ngIfなど)内にある場合、クエリは変更検出の実行後に解決されます。それ以外の場合、変更検出が実行される前に解決されます。

1
Samar Abdallah

Angular 8.にアップグレードした後、ngOnInitでViewChildがnullだったため、ここに来ました。

静的クエリはngOnInitの前に入力され、動的クエリ(静的:false)は後に入力されます。つまり、static:falseを設定した後、ngOnInitでviewchildがnullになった場合、static:trueに変更するか、ngAfterViewInitにコードを移動することを検討する必要があります。

https://github.com/angular/angular/blob/master/packages/core/src/view/view.ts#L332-L336 を参照してください

他の答えは正しいですし、なぜそうなのかを説明します:構造的なディレクティブに依存するクエリ。 ngIf内のViewChild参照は、このディレクティブの条件が解決された後、つまり変更検出後に実行する必要があります。ただし、static:trueを安全に使用して、ネストされていない参照のngOnInitの前にクエリを解決できます。この特定のケースでは、私にとってそうであったように、この例外に遭遇する最初の方法はnull例外である可能性が高いと述べています。

1
corolla