@ViewChildと@ContentChildの違いは何ですか?


回答:


256

Shadow DOMLight DOMの用語を使用して質問に回答します(Webコンポーネントに由来します。詳しくは、こちらをください)。一般に:

  • シャドウDOM-コンポーネントの内部DOMであり、(コンポーネントの作成者として)ユーザーが定義、エンドユーザーからは見えません。例えば:
@Component({
  selector: 'some-component',
  template: `
    <h1>I am Shadow DOM!</h1>
    <h2>Nice to meet you :)</h2>
    <ng-content></ng-content>
  `;
})
class SomeComponent { /* ... */ }
  • Light DOM-コンポーネントのエンドユーザーが使用するDOMです提供です。例えば:
@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 { /* ... */ }

だから、あなたの質問への答えは非常に簡単です:

違い@ViewChildrenとは@ContentChildrenつまり@ViewChildrenながらシャドウDOM内の要素の外観@ContentChildrenライトDOMで彼らのために見て。


10
Minko Gechew のブログエントリblog.mgechev.com/2016/01/23/…は、私にとってより理にかなっています。@ContentChildrenは、コンテンツプロジェクションによって挿入された子です(<ng-content> </ ng-content>間の子)。Minkosブログから:「一方で、特定のコンポーネントのホスト要素の開始タグと終了タグの間に使用される要素は、*コンテンツの子**と呼ばれます。」Angular2のシャドウDOMとビューのカプセル化については、こちらで説明しています:blog.thoughtram.io/angular/2015/06/29/…
westor

4
私にとっては、@TemplateChildren(の代わりに@ViewChildren)または @HostChildren(の代わりに@ContentChildren)の方がはるかに優れた名前であるように思われます。
superjos 2016年

35
@ViewChildren==あなた自身の子供; @ContentChildren==他人の子供
candidJ '20

107

名前として提案し、@ContentChildそして@ContentChildrenクエリが内部に存在するディレクティブを返します<ng-content></ng-content>、あなたのビューの要素を一方@ViewChild@ViewChildrenだけ直接あなたのビューテンプレート上にある要素を見てください。


したがって、ビューにコンポーネントがない場合を除き、@ ViewChild(ren)を使用します。その場合、@ ContentChild(ren)にフォールバックしますか?
Ben Taliadoros 2017

31

Angular Connectからのこのビデオには、ViewChildren、ViewChild、ContentChildren、およびContentChildに関する優れた情報があり ますhttps://youtu.be/4YmnbGoh49U

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

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

以下からmy-widgetの視点、comp-aであるContentChildcomp-bされますViewChildCompomentChildrenそしてViewChildrenxChildは、単一のインスタンスを返しながら、反復可能オブジェクトを返します。


これはより良い説明です。おかげで:)
ジェイブド'13

明確でシンプルな例を作成しましたが、MyWidgetのテンプレートは<comp-b><ng-content></ng-content></comp-b>正しいはず ですか?
arjel

1

例を挙げましょう。1つのホームコンポーネントと1つの子コンポーネントがあり、子コンポーネントの中に1つの小さな子コンポーネントがあります。

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

@viewChildrenを使用してホームコンポーネントのコンテキストですべての子要素を取得できるようになりました。これらの要素はホームコンポーネントのテンプレートに直接追加されるためです。ただし、<small-child>子コンポーネントのコンテキストから要素にアクセスしようとすると、子コンポーネントテンプレート内に直接追加されないため、アクセスできません。コンテンツプロジェクションを通じてホームコンポーネントによって子コンポーネントに追加されます。これが@contentChildの出番であり、@ contentChildで取得できます。

コントローラで要素参照にアクセスしようとすると、違いが発生します。@viewChildによってコンポーネントのテンプレートに直接追加されたすべての要素にアクセスできます。ただし、@ viewChildで投影された要素の参照を取得することはできません。投影された要素にアクセスするには、@ contentChildを使用する必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.