In the old Angular 1.x we could build directives and have an options to set "replace": true in the configuration which would allow you to tell Angular to replace the entire DOM element with whatever your directive was comprised of.
I am fairly new to Angular 2+, but so far we only seem to have 2 options for building a component in the same manner:
1) Use the element selector like this <app-my-component></app-my-component>
2) Use the attribute selector like this <div app-my-component></div>
The issue is I see problems with both of these:
Using method #1 can disrupt CSS stylings as Angular will place an extra DOM element into the page which means if you have an HTML structure like comprised of a <ul>
and children <li>
elements and you want to make the <li>
elements a reusable component then your resulting DOM looks like this:
<ul>
<app-my-component>
<li>Inner</li>
</app-my-component>
</ul>
Which would effectively break any CSS targeting ul > li
.
Using method #2 allows us to fix the CSS styling issue, but removes the abstraction that a component is supposed to provide as now a consumer of the component has to have knowledge about the element type needed:
<ul>
<li app-my-component>
Inner
</li>
</ul>
In the above case the developer has to know to use a <li>
in order for things to work properly. This is a very simple example, but more complex scenarios could be less intuitive to the developer causing headaches.
Take a look at this example. Due to the nature of the underlying HTML/CSS I had to setup these 2 (primary/secondary) components like this and use an internal <ng-content>
to display the navigation correctly. As you can see having to stick <li>
elements inside of the parent <div>
looks and feels weird and adds the need for the developer to know about the underlying HTML.
<div app-platform-navigation-primary label="Test" icon="account_box" link="#">
<li app-platform-navigation-secondary label="Test2" link="#"></li>
<li app-platform-navigation-secondary label="Test3" link="#"></li>
<li app-platform-navigation-secondary label="Test4" link="#"></li>
<li app-platform-navigation-secondary label="Test5" link="#"></li>
</div>
Summary
Overall, both methods have their pros and cons, but I feel like I could get the best of both worlds if we could still use the "replace" method which allows you to develop using method #1 which provides all of the abstraction you need, but would not add an "extra" DOM element onto the page which would allow CSS to continue to work.
What were the downfalls of doing this that caused the Angular team to remove these capabilities? And is there any solution to do it how I would like to do it?