I would like to simplify developper experience in my angular library. That´s why I´m trying to use a ng-content with a specific select which be automaticaly populated without the developper needs to add the class.
Example:
Application
app.component.html
<lib-frame-component>
<lib-panel-component [modal]="true"></lib-panel-component>
</lib-frame-component>
Library
lib-frame-component.html
<!-- developper should not need to use to include lib-panel-component(s) -->
<ng-content select='.modals-content'></ng-content>
lib-frame-component.ts
// get lib-panel-components inserted by the developper
@ContentChildren( LibPanelComponent, { descendants: false } ) directPanels: QueryList<PanelComponent>;
...
// Do something like that somewhere in the life cycle...
this.directPanels.forEach(( panelComponent: LibPanelComponent) => {
if ( panelComponent.modal === true ) {
// TODO : code to insert in ng-content.modals-content
}
}
How can I do this ?
CodePudding user response:
https://angular.io/guide/content-projection
Try to look throught the official docs.
If you do not use select on ng-content it would take content that will not be populated in ng-content's with select, by default.
CodePudding user response:
You cannot programmatically change the projected content inside ng-content because it is not meant to work this way. If you want to narrow down what is shown, you need to come up with a more specific selector, e.g:
<ng-content select="lib-panel-component[shown]"></ng-content>
Then, whoever is using your library can specify what needs to be shown like this:
<lib-frame-component>
<!-- this will be projected -->
<lib-panel-component [modal]="true" shown></lib-panel-component>
<!-- this will not be projected -->
<lib-panel-component></lib-panel-component>
</lib-frame-component>
Or, if you insist on programmatically changing stuff on the projected content (not advised), you can add an @Input property to the LibPanelComponent which then you can change inside lib-frame-component.ts:
this.directPanels.forEach(( panelComponent: LibPanelComponent) => {
if ( panelComponent.modal === true ) {
panelComponent.hidePanelContent = true;
}
}
And then, you'd need to wrap the component markup of LibPanelComponent in a container with an *ngIf, for example:
<ng-container *ngIf="!hidePanelContent">
<!-- LibPanelComponent markup -->
</div>
The second approach will leave you with a bunch of empty <lib-panel-component></lib-panel-component> components in the DOM.
