Suppose i have simple Bootstrap panel component with multiple transclusion slots. Template example:
<div class="panel panel-default"> <div class="panel-heading"> <ng-content select="my-panel-heading"></ng-content> </div> <div class="panel-body"> <ng-content select="my-panel-content"></ng-content> </div> </div>
I want to make panel-heading optional. How do i hide <div class="panel-heading">
element, if there is no content provided for <ng-content select="my-panel-heading"></ng-content>
The ng-content is used when we want to insert the content dynamically inside the component that helps to increase component reusability. Using ng-content we can pass content inside the component selector and when angular parses that content that appears at the place of ng-content.
Content projection is a pattern in which you insert, or project, the content you want to use inside another component. For example, you could have a Card component that accepts content provided by another component.
ng-container serves as a container for elements which can also accept structural directives but is not rendered to the DOM, while ng-template allows you to create template content that is not rendered until you specifically (conditionally or directly) add it to the DOM.
ng-content is an important concept to create reusable and flexible components. With the help of ng-content content can be projected by a parent component into a predefined slot. In some cases, you want to apply some styles to the projected content.
If you have a parent element of <ng-content>
with a template variable (#panelHeading
)
<div class="panel panel-default"> <div class="panel-heading" #panelHeading [hidden]="!showHeading"> <ng-content select="my-panel-heading"></ng-content> </div> <div class="panel-body"> <ng-content select="my-panel-content"></ng-content> </div> </div>
then you can query for it like
@ViewChild('panelHeading') panelHeading;
and set a property depending on whether there are children or not
constructor(private cdRef:ChangeDetectorRef) {} showHeading:boolean = false; ngAfterViewInit() { this.showHeading = this.panelHeading.nativeElement && this.panelHeading.nativeElement.children.length > 0; this.cdRef.detectChanges(); }
If <my-panel-heading>
is an Angular2 component, then you can also use
@ContentChild(MyPanelHeading) panelHeading:MyPanelHeading; constructor(private cdRef:ChangeDetectorRef) {} showHeading:boolean = false; ngAfterViewInit() { this.showHeading = this.panelHeading != null; this.cdRef.detectChanges(); }
You'd have to remove all your spaces but you could do this with CSS if you really cared about it (ng-content doesn't take up space):
.panel-heading:empty { display: none } <div class="panel-heading"><ng-content select="my-panel-heading"></ng-content></div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With