Here we can see that the layout is obvious – whether content is contained in the body, header or side-header is immediately clear, and using React’s children injecting content into each component is a cinch. This actually reads pretty similarly to how the page will show!

To show-off the benefits of this structure let’s add some styling.

Styling

Let’s add some classes to our common Page components, so we end up with:

Angular

To achieve a similar development experience we need to leverage Angular’s multiple transclusion. Those familiar with AngularJS (or Angular 1) might remember “transclusion” as a magic allowing some fancy DOM manipulation – Angular has kept a similar concept.

The components

As we did with the React app, we can quickly get something running with Angular, so let’s go straight into the components.

Immediately we see the structure is very similar to the React version. The components have had to be prefixed by “page-“ as they’re selectors and we don’t want to clash with the native HTML header and body. There’s also a little more of Angular getting in the way with its syntax [title]="'Angular Page'", but it’s quite light touch.

Diving into the components themselves, first we have the page.component

This looks quite different from the React page, as we have to define the HTML structure here and include placeholders for what’s to come. The ng-content allows the injection of DOM elements and is the Angular method of transclusion. In this case it is taking all of the header content.

We have a real looking angular component, page-body being used above in home.component.html, but this is really just a veneer across the ng-content and its selection. Using a select="page-body" we can limit where the content is injected into this page.component, so that only the body contents are included in the correct place. This way no new component needs to be written.

However, in the case of the page-header we do need a new component, as it itself will take transcluded content.

Again we need to set-up the correct placeholders for the correct content to be injected. This time the top ng-content is allowing for extra header material to be added.

In both of these components we demonstrate multiple transclusion – a fancy way of stating that there are multiple ng-contents allowing for different injection points. And as above, the page-side-header is not a real and registered Angular component, solely an entry point for the named content.

Wrapping this all up with the same stylesheet as before yields:

As we can see this page is identical in layout when rendered.

Notes

This page component has been wrapped up in an Angular Module for better exposure and re-use. As well as this the NO_ERRORS_SCHEMA has had to be imported and used in the app.module to prevent build errors with the unrecognised tags page-header etc.

Summary

It’s been demonstrated here that both frameworks allow for semantic components to control duplication and page layout, producing the same end result.

In my opinion Angular’s multiple transclusion model yields a steeper learning curve against leveraging React’s composability. The ng-content syntax is less readable to my eyes, and requires a clearer defined structure in which to consciously inject content. However once that’s abstracted away in the component I’d say that the consuming components are just as readable as their React counterparts.

While in React I had to create more components, their simplicity and small size doesn’t make it much of a hurdle at all. They are all equally readable and extendable, and don’t produce much clutter.

The Angular structure forces the consumers to ‘do the right thing’. If a page-side-header were placed inside the page-body then it would not be rendered, as it only belongs to the page-header (however if it were to become a separate component in its own right it would start to work). The React approach allows any component to be inserted anywhere in the structure, so requires more of a ‘good faith’ with the developer to make sure they don’t abuse the components (though this should be a clear mistake to see a header inside the body).

All in all a framework choice will most likely not come down to this issue, but it’s good to know that the solutions are there in both!