angular2-chapter08

Reusing Components with Content Projection

Check code at: https://github.com/wghglory/angular2-fundamental

Content Projection

Now in event-detail page, there's a list of sessions for that event. We want to collapse and expand every session when clicking the session div. Since this feature is quite common, and probably get reused somewhere else, we need to put this function into common folder.

  1. In session-list.component.html
<div class="row" *ngFor="let session of sessions">
    <div class="col-md-10">
        <!-- content projection -->
        <collapsible-well [title]="session.name">
            <h6>{{session.presenter}}</h6>
            <span>Duration: {{session.duration}}</span><br />
            <span>Level: {{session.level}}</span>
            <p>{{session.abstract}}</p>
        </collapsible-well>
        <!-- <div class="well">
            <h4>{{session.name}}</h4>
            <h6>{{session.presenter}}</h6>
            <span>Duration: {{session.duration}}</span><br />
            <span>Level: {{session.level}}</span>
            <p>{{session.abstract}}</p>
        </div> -->
    </div>
</div>
  1. create common/collapsible-well.component, and register it in module

Note: <ng-content> is responsible to show html inside its selector "collapsible-well": h6+span+span+p in this case

import { Component, Input } from '@angular/core'

@Component({
    selector: 'collapsible-well',
    template: `
        <div (click)="toggleContent()" class="well pointable">
            <h4 class="well-title">{{title}}</h4>
            <ng-content *ngIf="visible"></ng-content>
        </div>
    `
})
export class CollapsibleWellComponent {
    @Input() title: string;
    visible: boolean = true;

    toggleContent() {
        this.visible = !this.visible;
    }
}

Multiple Slot Content Projection

We also want to add a flame icon next to the session title if any session is hot. If we add this feature into collapsible-well template after <h4 class="well-title">{{title}}</h4>, this component is not generic.

session-list.component.html:

well-title and well-body attributes can be used as selectors in collapsible-well.component template. Attribute is better than class since it won't give us any conflict for a css class.

<div class="row" *ngFor="let session of sessions">
    <div class="col-md-10">

        <!-- multi slot content projection -->
        <collapsible-well>
            <div well-title>
                {{session.name}}
                <i *ngIf="session.voters.length>3" class="glyphicon glyphicon-fire" style="color:red;"></i>
            </div>

            <div well-body>
                <h6>{{session.presenter}}</h6>
                <span>Duration: {{session.duration}}</span><br />
                <span>Level: {{session.level}}</span>
                <p>{{session.abstract}}</p>
            </div>
        </collapsible-well>

        <!-- content projection -->
        <!-- <collapsible-well [title]="session.name">
            <h6>{{session.presenter}}</h6>
            <span>Duration: {{session.duration}}</span><br />
            <span>Level: {{session.level}}</span>
            <p>{{session.abstract}}</p>
        </collapsible-well> -->

        <!-- <div class="well">
            <h4>{{session.name}}</h4>
            <h6>{{session.presenter}}</h6>
            <span>Duration: {{session.duration}}</span><br />
            <span>Level: {{session.level}}</span>
            <p>{{session.abstract}}</p>
        </div> -->
    </div>
</div>

collapsible-well.component.ts updates template:

Note: ng-content with select is used to display the html. "select" can have id selector, class selector, etc. Attribute selector is best for multiple slot content projection

import { Component, Input } from '@angular/core'

@Component({
    selector: 'collapsible-well',
    template: `
        <div (click)="toggleContent()" class="well pointable">
            <h4>
                <ng-content select="[well-title]"></ng-content>
            </h4>
            <ng-content *ngIf="visible" select="[well-body]"></ng-content>
        </div>
    `
})
export class CollapsibleWellComponent {
    @Input() title: string;
    visible: boolean = true;

    toggleContent() {
        this.visible = !this.visible;
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 今天和老師溝通了孩子期末考試的情況。語文高分排名前三,很棒~數(shù)學(xué)滑鐵盧,跌到平均分以下,英語也低于平均分。感謝老師...
    爬山虎7544閱讀 402評(píng)論 0 0
  • 現(xiàn)在p圖軟件越來越智能,p圖越來越方便,效果越來越好,照片p的越來越美,“照片”因此也變成“照騙”了。即使沒有任何...
    q肥有大智慧閱讀 809評(píng)論 2 0
  • 近期目標(biāo)是財(cái)富增長!通過學(xué)習(xí)智慧和實(shí)踐智慧并用成功的案例傳播智慧,讓身邊更多的人接受智慧并學(xué)習(xí)智慧。讓世界因智慧而...
    belivePossible閱讀 140評(píng)論 0 1

友情鏈接更多精彩內(nèi)容