Açısal 8'de @ViewChild için yeni statik seçeneği nasıl kullanmalıyım?


208

Yeni Angular 8 view alt öğesini nasıl yapılandırmalıyım?

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

vs

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

Hangisi daha iyi? Ne zaman static:truevs kullanmalıyım static:false?

Yanıtlar:


240

Çoğu durumda kullanmak isteyeceksiniz {static: false}. Bunun böyle ayarlanması, bağlayıcı çözünürlüğe (yapısal yönergeler gibi *ngIf, etc...) bağlı olan sorgu eşleşmelerinin bulunmasını sağlayacaktır.

Ne zaman kullanılacağına örnek 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: falseDaha Açısal 9. okuyun varsayılan yedek davranış olacak burada ve burada

{ static: true }Seçenek anında gömülü görünüm oluşturma desteklemek tanıtıldı. Dinamik bir görünüm oluştururken ve öğesine erişmek istediğinizde TemplateRef, hataya ngAfterViewInitneden olacağı için bunu yapamazsınız ExpressionHasChangedAfterChecked. Statik bayrağı true olarak ayarlamak, ngOnInit'te görünümünüzü oluşturur.

Yine:

Diğer çoğu durumda, en iyi uygulama kullanmaktır {static: false}.

Bu { static: false }seçeneğin Açısal 9'da varsayılan olarak ayarlanacağını unutmayın static: true. Bu , seçeneği kullanmak istemediğiniz sürece statik bayrağın ayarlanmasının artık gerekli olmadığı anlamına gelir .

ng updateGeçerli kod tabanınızı otomatik olarak yükseltmek için açısal cli komutunu kullanabilirsiniz.

Bir taşıma kılavuzu ve bununla ilgili daha fazla bilgi için burayı ve buradan kontrol edebilirsiniz

Statik ve dinamik sorgular arasındaki fark nedir?

@ViewChild () ve @ContentChild () sorguları için statik seçenek, sorgu sonuçlarının ne zaman kullanılabilir olacağını belirler.

Statik sorgular (static: true) ile, görünüm oluşturulduktan sonra ancak değişiklik algılama çalışmadan önce sorgu çözülür. Ancak sonuç, ngIf ve ngFor bloklarındaki değişiklikler gibi görünümünüzdeki değişiklikleri yansıtacak şekilde asla güncellenmeyecektir.

Dinamik sorgularla (statik: false), sorgu @ViewChild () ve @ContentChild () için sırasıyla ngAfterViewInit () veya ngAfterContentInit () sonrasında çözümlenir. Sonuç, görünümünüzdeki ngIf ve ngFor bloklarındaki değişiklikler gibi değişiklikler için güncellenecektir.


Lütfen açısal dokümanlar için bağlantıyı güncelleyin (yayınlandıktan sonra değiştirildi) angular.io/api/core/ViewChild#description
Sachin Gupta

2
ChildView örneğine erişemiyorum. Her zaman tanımsız olduğunu söylüyor.
Nesan Mano

Açısal 9'daki statik seçeneği kaldırma hakkında bu konuda bir bağlantı sağlayabilir misiniz?
Alex Marinov

@AlexMarinov Açısal 9'da ne olacağını daha net hale getirmek için cevabımı güncelledim. Bununla ilgili bağlantı, göç kılavuzunda
Poul Kruijt

1
@ MinhNghĩa tüm bileşeni bileşenin şablonunun dışına yerleştirirseniz kullanabilirsiniz { static: true }, ancak içindeki ViewChild'e erişim için doğrudan bir gereksinim ngOnInityoksa, yalnızca { static: false }.
Poul Kruijt

88

Yani bir kural olarak aşağıdakiler için gidebilirsiniz:

  • { static: true }Eğer erişmek istediğinizde ihtiyaçları set olmak ViewChildin ngOnInit.

  • { static: false }yalnızca adresine erişilebilir ngAfterViewInit. Bu, *ngIfşablonunuzdaki öğeniz hakkında yapısal bir yönerge (örn. ) Olduğunda da gitmek istediğiniz şeydir .


2
Not: Açısal 9'da statik bayrak varsayılan olarak false değerine sahiptir, bu nedenle "herhangi bir {static: false} bayrağı güvenli bir şekilde kaldırılabilir". Belgeler: angular.io/guide/static-query-migration
Stevethemacguy

17

Açısal dokümanlardan

statik - değişiklik algılama çalıştırmadan önce sorgu sonuçlarının çözülüp çözülmeyeceği (örneğin yalnızca statik sonuçlar döndürün). Bu seçenek sağlanmazsa, derleyici varsayılan davranışına geri döner; bu, sorgu çözümlemesinin zamanlamasını belirlemek için sorgu sonuçlarını kullanmaktır. Herhangi bir sorgu sonucu iç içe bir görünümün içindeyse (örn. * NgIf), değişiklik algılama çalıştırıldıktan sonra sorgu çözülür. Aksi takdirde, değişiklik algılama çalışmadan önce çözülecektir.

static:trueÇocuk herhangi bir koşula bağlı değilse kullanmak daha iyi bir fikir olabilir . Elemanın görünürlüğü değişirse, daha static:falseiyi sonuçlar verebilir.

Not: Yeni bir özellik olduğundan, performans için karşılaştırmalar yapmamız gerekebilir.

Düzenle

@Massimiliano Sartoretto tarafından belirtildiği gibi, github taahhüdü size daha fazla bilgi verebilir.


3
Bu özelliğin arkasındaki resmi motivasyonları eklerim github.com/angular/angular/pull/28810
Massimiliano

2

Açısal 8'e yükselttikten sonra bir ViewChild ngOnInit'te boş olduğu için buraya geldi.

Statik sorgular ngOnInit'ten önce, dinamik sorgular (statik: yanlış) sonra doldurulur. Başka bir deyişle, static: false ayarladıktan sonra ngOnInit içinde bir viewchild artık null olursa, static: true olarak değiştirmeyi veya kodu ngAfterViewInit olarak değiştirmeyi düşünmelisiniz.

Bkz. Https://github.com/angular/angular/blob/master/packages/core/src/view/view.ts#L332-L336

Diğer yanıtlar doğrudur ve neden böyle olduğunu açıklayın: Yapısal yönergelere bağlı olan sorgular, örneğin bir ngIf içindeki bir ViewChild başvurusu, bu yönergenin koşulu çözüldükten sonra, yani değişiklik algılandıktan sonra çalıştırılmalıdır. Ancak, statik: true güvenli bir şekilde kullanılabilir ve böylece dürüst olmayan başvurular için ngOnInit önce sorguları çözmek. Bu özel davanın boş bir istisna olarak bahsetmesi benim için olduğu gibi bu özelliğe rastlayacağınız ilk yol olabilir.


1

child @angular 5+ token iki bağımsız değişkeni görüntüle ('yerel başvuru adı', statik: false | true)

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

doğru ve yanlış arasındaki farkı bilmek

statik - değişiklik algılama çalıştırmadan önce sorgu sonuçlarının çözülüp çözülmeyeceği (örneğin yalnızca statik sonuçlar döndürün). Bu seçenek sağlanmazsa, derleyici varsayılan davranışına geri döner; bu, sorgu çözümlemesinin zamanlamasını belirlemek için sorgu sonuçlarını kullanmaktır. Herhangi bir sorgu sonucu iç içe bir görünümün içindeyse (örn. * NgIf), değişiklik algılama çalıştırıldıktan sonra sorgu çözülür. Aksi takdirde, değişiklik algılama çalışmadan önce çözülecektir.


0

Ng8'de, ana bileşendeki alt bileşene ne zaman erişileceğini elle ayarlayabilirsiniz. Statik'i true olarak ayarladığınızda, üst bileşen yalnızca kancadaki bileşenin tanımını alır onInit: Örneğin:

 // You got a childComponent which has a ngIf/for tag
ngOnInit(){
  console.log(this.childComponent);
}

ngAfterViewInit(){
  console.log(this.childComponent);
}

Statik false olursa, tanımlamayı yalnızca ngAfterViewInit () 'de alırsınız, ngOnInit ()' de tanımsız kalırsınız.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.