在開發(fā)一個(gè)前端程序時(shí)鸣剪,肯定會(huì)有很多相似的邏輯或布局俏扩,這時(shí)就需要提取公共組件或樣式來盡可的復(fù)用代碼揩悄。在angular中卖哎,提供了ng-content來更方便的編寫組件和布局甫窟。
ng-content
- 在組件中嵌入內(nèi)容
- 在組件中嵌入模板代碼
- select屬性支持css選擇器(”#id”,”.class”等等)
使用
下面以表單中常見的布局為例:
<form-item>
<form-item-label>
手機(jī)號(hào)碼
</form-item-label>
<form-item-wrap>
<input name="phone" [(ngModel)]="phone" placeholder="請(qǐng)輸入手機(jī)號(hào)"/>
</form-item-wrap>
</form-item>
我們封裝了三個(gè)組件:form-item form-item-label form-item-wrap
我們期望form-item-label中的內(nèi)容展示頁面文字說明部分三椿,form-item-wrap展示頁面用戶輸入部分。
<form-item>
<form-item-label>
<!-- your html code -->
</form-item-label>
<form-item-wrap>
<!-- your html code -->
</form-item-wrap>
</form-item>
form-item組件代碼:
import { Component, ContentChild } from '@angular/core';
import { FormItemLabelComponent } from './form-item-lable.component';
import { FormItemWrapComponent } from './form-item-wrap.component';
@Component({
selector: 'form-item',
templateUrl: './form-item.component.html'
})
export class FormItemComponent {
@ContentChild(FormItemLabelComponent) itemLabel;
@ContentChild(FormItemWrapComponent) itemWrap;
}
html:
<div>
<div class="css實(shí)現(xiàn)">
<ng-content select="form-item-label" *ngIf="itemLabel"></ng-content>
</div>
<div class="css實(shí)現(xiàn)">
<ng-content select="form-item-wrap" *ngIf="itemWrap"></ng-content>
</div>
</div>
form-item-label組件代碼:
import { Component } from '@angular/core';
@Component({
selector: 'form-item-label',
template: '<ng-content></ng-content>'
})
export class FormItemLabelComponent {
}
form-item-wrap組件代碼:
import { Component } from '@angular/core';
@Component({
selector: 'form-item-wrap',
template: '<ng-content></ng-content>'
})
export class FormItemWrapComponent {
}
在組件form-item中通過ng-content的select屬性(使用的是css的element選擇器)投影form-item-label和form-item-wrap組件內(nèi)容嫉戚。
在form-item-label和form-item-wrap中則使用ng-content來嵌入模板代碼蹬挺,如果沒有ng-content則組件中的模板代碼無法展示维贺。(組件內(nèi)css樣式不再展示)
ContentChild
ContentChild 用來從通過 Content Projection 方式 (ng-content) 設(shè)置的視圖中獲取匹配的元素
在父組件的 ngAfterContentInit 生命周期鉤子中才能成功獲取通過 ContentChild 查詢的元素
它和viewChild是不同的
- ViewChild 用來從模板視圖中獲取匹配的元素
- 在父組件的 ngAfterViewInit 生命周期鉤子中才能成功獲取通過 ViewChild 查詢的元素
與css直接布局對(duì)比優(yōu)勢(shì)
本文中注冊(cè)頁面視效是左右布局,有些ux設(shè)計(jì)可能是上下布局巴帮,可能是點(diǎn)擊操作彈出文字說明布局等等溯泣,這些布局抽象成建模分為兩部分:文字說明部分和用戶操作部分。使用ng-content編寫組件榕茧,實(shí)際上相當(dāng)于頁面領(lǐng)域的建模垃沦,form-item-label是文字描述部分,form-item-wrap是用戶操作部分用押,不論ux ui的設(shè)計(jì)如何肢簿,但是建模是一定的。
組件化的優(yōu)勢(shì)
- 犧牲我一個(gè)蜻拨,幸福千萬家
- 以表單舉例:設(shè)計(jì)師要求左邊部分帶必選符號(hào)”*“或者”:”池充,如果是各個(gè)業(yè)務(wù)的開發(fā)童鞋來寫,后期設(shè)計(jì)一旦變更缎讼,就會(huì)存在更換不及時(shí)收夸,整個(gè)產(chǎn)品用戶體驗(yàn)不一致的情況,而如果通過form-item組件內(nèi)部搞定這件事情休涤,只需要開發(fā)這個(gè)組件的同事更新組件即可咱圆,保證了整體的一致性
- 項(xiàng)目團(tuán)隊(duì)有一個(gè)css高手保證組件樣式即可笛辟,極大的提升開發(fā)效率
總結(jié)
ng-content是組件化的神器,用好ng-content對(duì)一個(gè)項(xiàng)目有極大的便利序苏。