Угловая 2 предусматривает @ViewChild
, @ViewChildren
, @ContentChild
и @ContentChildren
декоратор для запроса потомков элементов отображения компонента.
В чем разница между первыми двумя и двумя последними?
Угловая 2 предусматривает @ViewChild
, @ViewChildren
, @ContentChild
и @ContentChildren
декоратор для запроса потомков элементов отображения компонента.
В чем разница между первыми двумя и двумя последними?
Ответы:
Я отвечу на ваш вопрос, используя терминологию Shadow DOM и Light DOM (это пришло из веб-компонентов, подробнее здесь ). В основном:
@Component({
selector: 'some-component',
template: `
<h1>I am Shadow DOM!</h1>
<h2>Nice to meet you :)</h2>
<ng-content></ng-content>
`;
})
class SomeComponent { /* ... */ }
@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.
@TemplateChildren
(вместо @ViewChildren
) или @HostChildren
(вместо @ContentChildren
) были бы гораздо более подходящие имена, поскольку в таком контексте все, о чем мы говорим, связано с представлением, а также с привязкой к содержимому.
@ViewChildren
== ваш собственный ребенок; @ContentChildren
== чей-то еще ребенок
Как следует из названия, @ContentChild
и @ContentChildren
запросы будут возвращать директивы, существующие внутри <ng-content></ng-content>
элемента вашего представления, тогда как @ViewChild
и @ViewChildren
смотреть только на элементы, которые находятся в вашем шаблоне представления напрямую.
Это видео от 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 возвращает один экземпляр.
<comp-b><ng-content></ng-content></comp-b>
правильным?
Давайте рассмотрим пример. У нас есть один домашний компонент и один дочерний компонент, а внутри дочернего компонента - один маленький дочерний компонент.
<home>
<child>
<small-child><small-child>
</child>
</home>
Теперь вы можете захватить все дочерние элементы в контексте домашнего компонента с помощью @viewChildren, потому что они непосредственно добавляются в шаблон домашнего компонента. Но когда вы пытаетесь получить доступ к <small-child>
элементу из контекста дочернего компонента, вы не можете получить к нему доступ, потому что он не добавляется непосредственно в шаблон дочернего компонента. Он добавляется через проекцию контента в дочерний компонент домашним компонентом. Вот где приходит @contentChild, и вы можете получить его с помощью @contentChild.
Разница возникает при попытке доступа к элементам ссылки в контроллере. Вы можете получить доступ ко всем элементам, которые непосредственно добавляются в шаблон компонента с помощью @viewChild. Но вы не можете получить ссылку на проецируемые элементы с помощью @viewChild. Для доступа к проецируемому элементу вы должны использовать @contentChild.