[Angular] ViewChild or ContentChild

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.

Example

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

Display projected content

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