I recently came across some interesting behavior with Angular's
ng-content that I wanted to jot down so I can search for some answers. NgContent isn't well documented.
ng-content is to be used like any other element. This is great, especially for rendering in default content. For example, a component that can transclude some content but if for some reason nothing is nested into it, it will show a default state.
But what if you don't need anything within the opening and closing tags? You'd think that just
<ng-content /> would be a nice and simple way to signal where to place the included content, but attempting to do so generates the following error:
Template parse errors: Only void and foreign elements can be self closed "ng-content"[ERROR ->]<ng-content />
Seems weird to me. This may be by design.
One of the features of
ng-content is that you can use the
select attribute on it to pull transcluded content into a specific location.
<!-- my-component.html --><div><ng-content select=".title"></ng-content><ng-content select=".subtitle"></ng-content></div>
This is great for enforcing layout in a specific way. Except... it has a major caveat, at least in my opinion. This select only seems to match immediate children only, nothing else.
So using the above
my-component, this belwo works while placing the
title above the
<my-component><p class="subtitle">world</p><h2 class="title">Hello</h2></my-component>
but then this doesn't! Nothing is rendered.
<my-component><div><h2 class="title">Hello</h2><p class="subtitle">world</p></div></my-component>
It can't find these same elements because they're wrapped in an extra div? I would have thought that it would match those elements as well, just like
querySelector or CSS selectors would. If I only wanted immediate children I would have used something like
select="> .title". My assumption that it used standard selectors is wrong? 🤷♂️ That sucks.