Angular Transclusion ng-content multiple ng-contnet
▌Introduction
In AngularJS, we use ngTransclude to capture what we want to put into directive template in the parent’s markup. (See this sample code on Codepen)
In Angular, ng-content is used for transclusion. In
this sample, we will learn
1.
Transclusion with ng-content
2.
Multiple ng-content
▌Environment
▋Angular 2.4.0
▋Angular CLI
1.0.0-beta.31
▌Implement
▋Transclusion with ng-content
First take a look at our original parent and child
components without transclusion.
▋ Parent component
<div class="width light-gray">
<ul class="index-list-vertical" id="prodCatsDiv">
<div *ngFor="let prod of (products$ | async)">
<main-product [prod]="prod">
</main-product>
</div>
</ul>
</div>
▋ Child component
<li style="min-height:150px;">
<a href="">{{prod.title}}</a>
<img src="{{prod.listPhoto}}" alt="{{prod.title}}" width="220" height="99">
<ul *ngFor="let prod of prod.subProducts; let i = index;">
<li *ngIf="i<3">{{prod.title}}</li>
</ul>
<ul *ngIf="prod.subProducts.length>3" style="text-align: right;">
<li>... More</li>
</ul>
</li>
Now let’s say we would like to put a “sub-products
count” near each main product’s title like the below picture without sending
more information to child component.
It’s time to use Transclusion.
Add the markup to the parent compoent
and put ng-content on the right place in the child component’s template.
▋Parent component
<div class="width light-gray">
<ul class="index-list-vertical" id="prodCatsDiv">
<div *ngFor="let prod of (products$ | async)">
<main-product [prod]="prod">
<button type="button" class="btn-raised btn btn-primary btn-circle btn-xs">
{{prod.subProducts.length}}
</button>
</main-product>
</div>
</ul>
</div>
▋ Child component
<li style="min-height:150px;">
<a href="">{{prod.title}}</a>
<ng-content></ng-content>
<img src="{{prod.listPhoto}}" alt="{{prod.title}}" width="220" height="99">
<ul *ngFor="let prod of prod.subProducts; let i = index;">
<li *ngIf="i<3">{{prod.title}}</li>
</ul>
<ul *ngIf="prod.subProducts.length>3" style="text-align: right;">
<li>... More</li>
</ul>
</li>
And the result :
▋Multiple ng-content
What if there are multiple
markup on parent and we should put multiple ng-content on the child? It’s easy by just give them names.
Let’s try pulling the content
in the following picture from child to parent.
▋Parent component
Add the property names “subProdsCnt”
and “more” on the markups.
<ul class="index-list-vertical" id="prodCatsDiv">
<div *ngFor="let prod of (products$ | async)">
<main-product [prod]="prod">
<button type="button" subProdsCnt class="btn-raised btn btn-primary btn-circle btn-xs">
{{prod.subProducts.length}}
</button>
<ul more *ngIf="prod.subProducts.length>3" style="text-align: right;">
<li>... More</li>
</ul>
</main-product>
</div>
</ul>
▋Child component
Use the property: select, to map the parent’s markups.
<li style="min-height:150px;">
<a href="">{{prod.title}}</a>
<ng-content select="[subProdsCnt]"></ng-content>
<a href="">
<img src="{{prod.listPhoto}}" alt="{{prod.title}}" width="220" height="99">
</a>
<ul *ngFor="let prod of prod.subProducts; let i = index;">
<li *ngIf="i<3">{{prod.title}}</li>
</ul>
<ng-content select="[more]"></ng-content>
</li>
That makes multiple
ng-content work fine.
▌Reference
沒有留言:
張貼留言