Angular has it's many layers of abstraction which has an impact on how common web terminologies are used in it's documentation.
In Angular there is view DOM an content DOM. Only the view DOM has knowledge of the descending/encapsulated components. Content DOM only has know of the template provided by the component at hand or content injected via <ng-content>
.
ViewChild is comparable to the Shadow DOM in web component terminology which is an encapsulated sub-DOM attached to the host via what is called a Shadow Host.
More on Shadow DOM: https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM
ContentChild is comparable to Light DOM in web component terminology which is simply the normal plain DOM tree inside a HTML element. It simply grab the "content" within the template of an element.
Lets say you have a widget component which contains component-b
and while using this component you also include a component-a
:
@Component({
selector: 'my-widget',
template: `<component-b/>`,
})
class MyWidget {}
@Component({
template: `
<my-widget>
<component-a/>
</my-widget>
`,
})
class App {}
Inside the App component, you can refer to component-b
using a ViewChild, which reaches out to the encapsulated my-widget
component and it's template.
Also inside App, component-a
has been projected into my-widget
. You can refer to component-a
using a ContentChild inside of my-widget
like this:
@Component({
selector: 'my-widget',
template: `<component-b/>`,
})
class MyWidget {
@ContentChild(ComponentA) componentA: ComponentA
}
Video explaining the 2 child types: https://youtu.be/4YmnbGoh49U?t=403
Content that are projected into a comoponent can be referenced using @ContentChild
and @ContentChildren
, but these contents are not diplayed.
For the purpose of displaying projected content, Angular has the <ng-content>
element. An example: https://stackblitz.com/edit/angular-contentchildren-rwrgb5-n5f48v