Какая разница между @ViewChild и @ContentChild?

Angular 2 предоставляет @ViewChild, @ViewChildren, @ContentChild и @ContentChildren для запроса @ContentChildren элементов компонента.

Какая разница между первыми двумя и двумя последними?

Ответ 1

Я отвечу на ваш вопрос, используя терминологию Shadow DOM и Light DOM (она пришла из веб-компонентов, подробнее здесь). В общем:

  • Shadow 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 ищет элементы в Shadow DOM, а @ContentChildren ищет их в Light DOM.

Ответ 2

Как следует из названия, запросы @ContentChild и @ContentChildren возвращают директивы, существующие внутри элемента <ng-content></ng-content> вашего представления, тогда как @ViewChild и @ViewChildren видят только элементы, которые находятся в вашем шаблоне представления напрямую.

Ответ 3

Это видео из 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 есть ContentChild, а comp-b - ViewChild. CompomentChildren и ViewChildren возвращают итерацию, в то время как xChild возвращает один экземпляр.