Home > Mobile >  How to include programmatically in ng-content some components filtered by specific tagname in angula
How to include programmatically in ng-content some components filtered by specific tagname in angula

Time:01-19

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.

  •  Tags:  
  • Related