One of the main concepts about Angular is to build reusable components. That means having a component with static and dynamic content. A perfect example is a button component. The purpose is to have a single button component, which we can use several times in a project, but with a different text.
First, let's take a look at how we would design the button component without ng-content. We define an input value and using curly braces to display the text.
When using curly braces the text of the button is coming from the component itself. While this solution does the job, there is a better one out there:
Instead of using curly braces and keeping track of the input value, we can pass the value into the component from its execution context using <ng-content>.
ng-content is similar to ng-transclude in AngularJs. It works as a placeholder. Whatever content is placed between the button component will be displayed instead of ng-content.
The use of ng-content removes complexity, making the code cleaner and more readable. The good thing is we are not limited to just one ng-content element.
Using multiple ng-content elements
We can define multiple content slot using
<ng-content></ng-content> and the Selector
select. Let's create a card component with a header, content and footer section.
If we are using the elements which we defined via select, Angular will throw the following error:
Template parse errors:
'card-header' is not a known element:
1. If 'card-header' is an Angular component, then verify that it is part of this module.
2. If 'card-header' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.
That happens because Angular doesn't know our elements <card-header>, <card-content> and <card-footer>. There are either components, directive nor known HTML elements. We can solve this problem by adding the schema
NO_ERRORS_SCHEMA to our AppModule.
The benefits of using ng-content are:
- it removes complexity from components,
- it makes the code cleaner and more readable.