angular中的ng-content

在开发一个前端程序时,肯定会有很多相似的逻辑或布局,这时就需要提取公共组件或样式来尽可的复用代码。在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的设计如何,但是建模是一定的。

组件化的优势

  1. 牺牲我一个,幸福千万家
  2. 以表单举例:设计师要求左边部分带必选符号”*“或者”:”,如果是各个业务的开发童鞋来写,后期设计一旦变更,就会存在更换不及时,整个产品用户体验不一致的情况,而如果通过form-item组件内部搞定这件事情,只需要开发这个组件的同事更新组件即可,保证了整体的一致性
  3. 项目团队有一个css高手保证组件样式即可,极大的提升开发效率

总结

ng-content是组件化的神器,用好ng-content对一个项目有极大的便利。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 154,657评论 23 678
  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 11,754评论 1 91
  • ——被安利之后种草非常想玩甚至想实况的游戏系列之一—— 一个多月前的某一天晚上,很凑巧地赶上了岚少的直播。 然后就...
    佳木繁玥阅读 402评论 0 4
  • 属性说明 名称 物品名称 价格 价格
    玉面笑客阅读 5,063评论 1 0
  • 【原文】有子曰:“礼之用,和为贵。先王之道,斯为美。小大由之,有所不行;知和而和,不以礼节之,亦不可行也。” 【译...
    筱荭阅读 95评论 0 0