博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Angular-3种创建动态内容的方式
阅读量:6595 次
发布时间:2019-06-24

本文共 2966 字,大约阅读时间需要 9 分钟。

写在最前,本文提到的“模板”都是ng-template;假设的模态组件也只是实现模态内容;为了缩减文章的篇幅,只保留了重要的部分。完整的例子在 。
在开发过程中,难免会遇到公共组件需要Input模板或input组件的时候,以增加公共组件交互或展示的灵活性。
题外话:input组件的方式,可以扩展为依靠服务在业务模块中进行配置,以达到每个模块所用的同一个公共组件拥有不同的交互。下一篇文章将会谈谈。

1. 使用 ngTemplateOutlet 和 ngComponentOutlet

ngTemplateOutlet: 根据一个提前备好的 TemplateRef 插入一个内嵌视图。ngComponentOutlet: Instantiates a single Component type and inserts its Host View into current View. NgComponentOutlet provides a declarative approach for dynamic component creation.
假设要写一个表格组件,名为wtable,需要自定义单元格内容,组件ts有如下内容。
  • 使用场景
{
{column}}: {
{data}}
{
{index}} 行
行数据: {
{row | json}}
复制代码
  • wtable组件的html
            
复制代码
  • wtable组件ts
// 此处为内部变量传递给外部模板使用,所需的数据  outCellContext(cellKey, cellValue, row, index) {    return {      $implicit: cellValue, // 默认传出cellValue数据      column: cellKey, // 指定字段      row: row, // 行数据      index: index // 行索引    }  }}复制代码

2. 使用ViewContainerRef

表示可以将一个或多个视图附着到组件中的容器。
假设要写一个模态框组件wmodal,需要将模板或组件在模态框里展示。但是又不想html里用*ngIf来判断内容的显示,两个三个还可以接受,那要是7、8个或以上呢?让我们看看下面这个例子。
  • 使用场景
data: {
{data | json}}
other: {
{other}}
复制代码
  • 在wmodal内需要做点什么呢?首先是html
// 占个位,这里我要放传入的模板或组件了  
复制代码
  • 接着是wmodal的ts
ngAfterContentInit() {  // 依然是判断content类型  if (this.content instanceof Type) {    const comp = this.container.createComponent(this._compFac.resolveComponentFactory(this.content));    // 将组件所需参数合并到组件实例中    if (this.compParams) {      Object.assign(comp.instance, this.compParams);    }    // 订阅组件    for (const prop in comp.instance) {      if (comp.instance.hasOwnProperty(prop)) {        const subject = comp.instance[prop];        // 筛选组件output事件        if (subject instanceof EventEmitter) {          this._compSubs.push(            // 订阅组件output事件            subject.subscribe(data => {              this.compOut.emit(data);            })          );        }      }    }  } else {    // 创建模板就比较简单了    // 留意一下第二个参数,若是需要将组建的某些数据传出则可以这样    const _data = {a: 1, b: 2};    this.container.createEmbeddedView(this.content, {
$implicit: _data, other: 2}); }}复制代码

3. 使用ApplicationRef

A reference to an Angular application running on a page.
假设还是modal组件
  • 使用场景
复制代码
  • 惯例,wmodal2 html
复制代码
  • wmodal2 ts
ngAfterContentInit() {  const comp = this._compFaRes.resolveComponentFactory(this.content).create(this._injector);  this._e.nativeElement.appendChild(comp.location.nativeElement);  // 此处与第2点一样,订阅output和给input赋值  // 去掉timeout你就知道为什么了  // 具体原因可以看我专栏的的第一篇文章  const timeId = setTimeout(() => {    this._appref.attachView(comp.hostView);    clearTimeout(timeId);  }, 100)}复制代码

结束语

本文并未对3种方式进行对比,只是个人对于3种方式的使用理解。 简单的总结一下:
  • 使用1,会让html代码比较多,不易维护;而且1是通过2来实现得, ;
  • 1、2都需要插座代码(可见的outlet),对于模板的创建都需要context来传递变量,3不需要插座代码;
  • 2是比较常见的使用方式
  • 使用3的方式来仅可以创建组件且还有更大的用处
  • 创建组件都需要手动为input赋值并订阅output
有兴趣的还可以看看angular源码,其中 和 皆是由第2种方式来实现得。

参考资料:

转载于:https://juejin.im/post/5cc56f66e51d456e3428c192

你可能感兴趣的文章
我的友情链接
查看>>
一行命令获取当前JVM所有可设置的参数以及当前默认值
查看>>
Linux mint 14下的powerDNS+mysql+powerAdmin搭建个性DNS域名解析服务器
查看>>
Red Hat EnterPrise Linux 5.4下web服务器的综合使用(普通站点、虚拟主机、安全性、...
查看>>
unbantu安装 mysql --- 百度云
查看>>
JS中的默认行为
查看>>
从oracle到mysql,主从到分库,一个普通项目数据库架构的变迁
查看>>
selenium层级定位及鼠标键盘操作
查看>>
SpringBoot跨域问题解决方案
查看>>
(转载)hibernate3.0配置文件模板
查看>>
46、练习:输出指定目录下的所有文件名称
查看>>
IP地址与数字地址相互转换
查看>>
Knockout.Js官网学习(创建自定义绑定)
查看>>
python 抽象类、抽象方法、接口、依赖注入、SOLIP
查看>>
字符串连接[不用库函数]
查看>>
新建一个express工程,node app无反应
查看>>
OCM_第十一天课程:Section5 —》数据仓库
查看>>
水晶报表
查看>>
cogs 539. 牛棚的灯
查看>>
SQL SERVER 备份数据库到指定路径语句
查看>>