Write Compound Components

Part 2 of Advanced Angular Component Patterns

Isaac Mann
Angular In Depth
2 min readJan 4, 2018

--

Photo by Samuel Zeller on Unsplash

AngularInDepth is moving away from Medium. More recent articles are hosted on the new platform inDepth.dev. Thanks for being part of indepth movement!

01 Build a Toggle Component
03a Communicate Between Components Using Dependency Injection

The simple <toggle> component we built in Part 1 is not incredibly useful.

Goal:

What we really want is to allow the user of the toggle to display custom content based on the state of the <toggle>.

Implementation:

Enter compound components. We create three new components <toggle-button>, <toggle-on>, and <toggle-off>. Each one works in tandem with the parent <toggle> component to display different parts of the component. <toggle-button> renders the actual switch that toggles the parent state. <toggle-on> will render everything inside of it if the toggle state is on. <toggle-off> will render everything inside of it if the toggle state is off. The <toggle> component uses the @ContentChild decorator to get a reference to the three other child components and then takes care of communicating state changes between them.

Outcome:

This set up allows the user of the <toggle> component to customize what they want to appear when the toggle is on or off and where the button should be placed with respect to that content. Try moving the child components around in the stack blitz project below. You can wrap them in whatever nested html tags you want, as long as those three components stay inside the <toggle> component, everything will work.

Related Topics:

@ContentChild will return a reference to the first matching component or directive within the content of your component. i.e. <toggle> This is the content </toggle>. If you want all the matching components, use @ContentChildren. If you want to get a reference to components that you defined in the view template of your component, use @ViewChild or @ViewChildren. The view looks like template: 'This is the view' or templateUrl: './my.component.html'.

--

--