@ViewChild ve @ContentChild arasındaki fark nedir?


189

Eğik 2 sağlar @ViewChild, @ViewChildren, @ContentChildve @ContentChildrenbir bileşenin alt öğeleri sorgulamak için dekoratörler.

İlk ikisi ile son ikisi arasındaki fark nedir?


3
Bu bağlantı aşağıdaki cevapları okuduktan sonra bana blog.mgechev.com/2016/01/23/… yardımcı oldu . Şerefe :)
Gopinath Shiva

Yanıtlar:


256

Sorunuzu Shadow DOM ve Light DOM terminolojisini kullanarak cevaplayacağım (web bileşenlerinden gelmiştir, daha fazla bilgi için buraya bakın ). Genel olarak:

  • Gölge DOM - bileşeninizin sizin tarafınızdan ( bileşenin yaratıcısı olarak ) tanımlandığı ve son kullanıcıdan gizlenendahili bir DOM'dur. Örneğin:
@Component({
  selector: 'some-component',
  template: `
    <h1>I am Shadow DOM!</h1>
    <h2>Nice to meet you :)</h2>
    <ng-content></ng-content>
  `;
})
class SomeComponent { /* ... */ }
  • Hafif DOM - bileşeninizin son kullanıcısının bileşeninize sağladığı bir DOM. Örneğin:
@Component({
  selector: 'another-component',
  directives: [SomeComponent],
  template: `
    <some-component>
      <h1>Hi! I am Light DOM!</h1>
      <h2>So happy to see you!</h2>
    </some-component>
  `
})
class AnotherComponent { /* ... */ }

Yani, sorunuzun cevabı oldukça basit:

Arasındaki fark @ViewChildrenve @ContentChildrenolmasıdır @ViewChildreniken Gölge DOM'da elementler için göz @ContentChildrenIşık DOM onlar için bakmak.


10
Minko Gechew'dan blog.mgechev.com/2016/01/23/… blog girişi bana daha anlamlı geliyor. @İçerikÇocuklar içerik projeksiyonu (<ng-content> </ng-content> arasındaki çocuklar) tarafından eklenen çocuklardır. Minkos Blog'dan: "Öte yandan, belirli bir bileşenin ana bilgisayar öğesinin açılış ve kapanış etiketleri arasında kullanılan ** öğelere * içerik alt öğeleri ** denir." Gölge DOM ve Angular2'deki görünüm kapsüllemesi burada açıklanmaktadır: blog.thoughtram.io/angular/2015/06/29/… .
westor

4
Bana göre kulağa @TemplateChildren(yerine @ViewChildren) veya @HostChildren(yerine @ContentChildren) çok daha iyi isimler gibi gelebilir, çünkü böyle bir bağlamda bahsettiğimiz her şey görünümle ilgilidir ve wrt bağlama da içerikle ilgilidir.
superjos

35
@ViewChildren== kendi çocuğunuz; @ContentChildren== başkasının çocuğu
candidJ

107

Adından da anlaşılacağı gibi @ContentChildve @ContentChildrensorgular içindeki mevcut direktifleri dönecektir <ng-content></ng-content>oysa Görünümünüzün elemanı @ViewChildve @ViewChildrensadece doğrudan görünüm şablonu olan unsurların bak.


Görünümünüzde bileşenler yoksa @ViewChild (ren) kullanın, bu durumda @ContentChild (ren) 'e geri dönün.
Ben Taliadoros

31

Angular Connect'teki bu video, ViewChildren, ViewChild, ContentChildren ve ContentChild hakkında mükemmel bilgiye sahip https://youtu.be/4YmnbGoh49U

@Component({
  template: `
    <my-widget>
      <comp-a/>
    </my-widget>
`
})
class App {}

@Component({
  selector: 'my-widget',
  template: `<comp-b/>`
})
class MyWidget {}

Gönderen my-widgetbireyin perspektifinden, comp-abir ContentChildve comp-bbir ViewChild. CompomentChildrenve ViewChildrenxChild tek bir örneği döndürürken yinelenebilir bir değer döndürür.


Bu daha iyi bir açıklama. Teşekkürler :)
Javeed

Net ve basit bir örnek yaptınız, ancak MyWidget'ın şablonu <comp-b><ng-content></ng-content></comp-b>doğru mu?
arjel

1

Bir örnek verelim, bir ev bileşenimiz ve bir alt bileşenimiz var ve alt bileşen içinde bir küçük alt bileşen var.

<home>
     <child>
           <small-child><small-child>
     </child>
</home>

Artık @viewChildren ile ev bileşeni bağlamındaki tüm alt öğeleri yakalayabilirsiniz, çünkü bunlar doğrudan ev bileşeni şablonuna eklenir. Ancak, <small-child>öğeye alt bileşen bağlamından erişmeye çalıştığınızda, alt bileşen şablonuna doğrudan eklenmediği için ona erişemezsiniz. İçerik bileşeni, ana bileşen tarafından alt bileşene eklenir. İşte @contentChild devreye girer ve @contentChild ile yakalayabilirsiniz.

Fark, denetleyicideki öğe başvurusuna erişmeye çalıştığınızda oluşur. @ViewChild tarafından doğrudan bileşen şablonuna eklenen tüm öğelere erişebilirsiniz. Ancak @viewChild ile yansıtılan öğeler referansını yakalayamazsınız Yansıtılan öğeye erişmek için @contentChild kullanmanız gerekir.

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.