在開發一個前端程序時,肯定會有很多相似的邏輯或布局,這時就需要提取公共組件或樣式來盡可的復用代碼。在angular中,提供了ng-content來更方便的編寫組件和布局。
ng-content
- 在組件中嵌入內容
- 在組件中嵌入模板代碼
- select屬性支持css選擇器(”#id”,”.class”等等)
使用
下面以表單中常見的布局為例:
<form-item>
<form-item-label>
手機號碼
</form-item-label>
<form-item-wrap>
<input name="phone" [(ngModel)]="phone" placeholder="請輸入手機號"/>
</form-item-wrap>
</form-item>
我們封裝了三個組件:form-item form-item-label form-item-wrap
我們期望form-item-label中的內容展示頁面文字說明部分,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實現">
<ng-content select="form-item-label" *ngIf="itemLabel"></ng-content>
</div>
<div class="css實現">
<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組件內容。
在form-item-label和form-item-wrap中則使用ng-content來嵌入模板代碼,如果沒有ng-content則組件中的模板代碼無法展示。(組件內css樣式不再展示)
ContentChild
ContentChild 用來從通過 Content Projection 方式 (ng-content) 設置的視圖中獲取匹配的元素
在父組件的 ngAfterContentInit 生命周期鉤子中才能成功獲取通過 ContentChild 查詢的元素
它和viewChild是不同的
- ViewChild 用來從模板視圖中獲取匹配的元素
- 在父組件的 ngAfterViewInit 生命周期鉤子中才能成功獲取通過 ViewChild 查詢的元素
與css直接布局對比優勢
本文中注冊頁面視效是左右布局,有些ux設計可能是上下布局,可能是點擊操作彈出文字說明布局等等,這些布局抽象成建模分為兩部分:文字說明部分和用戶操作部分。使用ng-content編寫組件,實際上相當于頁面領域的建模,form-item-label是文字描述部分,form-item-wrap是用戶操作部分,不論ux ui的設計如何,但是建模是一定的。
組件化的優勢
- 犧牲我一個,幸福千萬家
- 以表單舉例:設計師要求左邊部分帶必選符號”*“或者”:”,如果是各個業務的開發童鞋來寫,后期設計一旦變更,就會存在更換不及時,整個產品用戶體驗不一致的情況,而如果通過form-item組件內部搞定這件事情,只需要開發這個組件的同事更新組件即可,保證了整體的一致性
- 項目團隊有一個css高手保證組件樣式即可,極大的提升開發效率
總結
ng-content是組件化的神器,用好ng-content對一個項目有極大的便利。