新しいAngular 8ビューの子を構成するにはどうすればよいですか?
@ViewChild('searchText', {read: ElementRef, static: false})
public searchTextInput: ElementRef;
対
@ViewChild('searchText', {read: ElementRef, static: true})
public searchTextInput: ElementRef;
どちらが良いですか? static:true
対static:false
はいつ使用する必要がありますか?
ほとんどの場合、{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ブロックの変更など、ビューの変更に対して更新されます。
したがって、経験則として、次のことを実行できます。
{ static: true }
は、ViewChild
内のngOnInit
にアクセスするときに設定する必要があります。
{ static: false }
はngAfterViewInit
でのみアクセスできます。また、これは、構造的なディレクティブがある場合(つまり、*ngIf
)テンプレートの要素に。
angular docs
static-変更検出の実行前にクエリ結果を解決するかどうか(つまり、静的な結果のみを返す)。このオプションが提供されない場合、コンパイラはデフォルトの動作に戻ります。つまり、クエリ結果を使用してクエリ解決のタイミングを決定します。クエリの結果がネストされたビュー(* ngIfなど)内にある場合、クエリは変更検出の実行後に解決されます。それ以外の場合、変更検出が実行される前に解決されます。
子が条件に依存しない場合は、static:true
を使用することをお勧めします。要素の可視性が変更された場合、static:false
はより良い結果をもたらす可能性があります。
PS:新しい機能なので、パフォーマンスのベンチマークを実行する必要があるかもしれません。
@Massimiliano Sartorettoが述べたように、 github commit はより多くの洞察を与えるかもしれません。
子の@angular 5+トークン2つの引数を表示( 'local reference name'、static:false | true)
@ViewChild('nameInput', { static: false }) nameInputRef: ElementRef;
真と偽の違いを知るには、これをチェックしてください
static-変更検出を実行する前にクエリ結果を解決するかどうか(つまり、静的な結果のみを返す)。このオプションが提供されない場合、コンパイラはデフォルトの動作に戻ります。つまり、クエリ結果を使用してクエリ解決のタイミングを決定します。クエリの結果がネストされたビュー(* ngIfなど)内にある場合、クエリは変更検出の実行後に解決されます。それ以外の場合、変更検出が実行される前に解決されます。
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例外である可能性が高いと述べています。