Angular使用总结 --- 通过指令动态添加组件

时间:2022-11-04 19:33:50

  之前自己写的公共组件,都是会先引入,需要调起的时候再通过service控制公共组件状态、值、回调函数什么的。但是有一些场景不适合这种方式,还是动态添加组件更加好。通过写过的一个小组件来总结下。

创建组件

  场景:鼠标移动到图标上时,展示解释性的说明文字。那就需要创建一个普通的tooltip组件。如下:

<aside class="hover-tip-wrapper">
<span>{{tipText}}</span>
</aside>

HTML

import { Component, OnInit } from '@angular/core';

@Component({
selector: 'app-hovertip',
templateUrl: './hovertip.component.html',
styleUrls: ['./hovertip.component.scss']
})
export class HovertipComponent implements OnInit { public tipText: string;
constructor() { } ngOnInit() {
} }

ts

.hover-tip-wrapper{
width: max-content;
position: absolute;
height: 30px;
line-height: 30px;
bottom: calc(100% + 5px);
right: calc( -10px - 100%);
background-color: rgba(#000000,.8);
padding: 0 5px;
border-radius: 3px; &::after{
content: '';
position: absolute;
height:;
width:;
border: 4px solid transparent;
border-top-color: rgba(#000000,.8);
left: 10px;
top: 100%;
} span {
color: #ccc;
font-size: 12px;
}
}

scss

  非常简单的一个组件,tipText来接收需要展示的文字。

  需要注意的是,声明组件的时候,除了需要添加到declarations中外,还记得要添加到entryComponents中。

entryComponents: [HovertipComponent],
declarations: [HovertipComponent, HovertipDirective]

  那entryComponents这个配置项是做什么的呢?看源码注释,大概意思就是:Angular会为此配置项中的组件创建一个ComponentFactory,并存放在ComponentFactoryResolver中。动态添加组件时,需要用到组件工厂,所以此配置是必不可少的。

Angular使用总结 --- 通过指令动态添加组件

创建指令

  通过指令为目标元素绑定事件,控制创建组件、传递tipText以及组件的销毁。

import { Input , Directive , ViewContainerRef , ComponentRef, ComponentFactory, HostListener , ComponentFactoryResolver} from '@angular/core';
import { HovertipComponent } from './hovertip.component';
@Directive({
selector: '[appHovertip]'
})
export class HovertipDirective { public hovertip: ComponentRef<HovertipComponent>;
public factory: ComponentFactory<HovertipComponent>;
constructor(
private viewContainer: ViewContainerRef,
private resolver: ComponentFactoryResolver
) {
// 获取对应的组件工厂
this.factory = this.resolver.resolveComponentFactory(HovertipComponent);
}
@Input('appHovertip') tipText: string;
 
// 绑定鼠标移入的事件
@HostListener('mouseenter') onmouseenter() {
   // 清空所有的view
   this.viewContainer.clear();
// 创建组件
this.hovertip = this.viewContainer.createComponent(this.factory);
// 向组件实例传递参数
this.hovertip.instance.tipText = this.tipText;
}
 
 // 绑定鼠标移出时的事件
@HostListener('mouseleave') onmouseleave() {
if (this.hovertip) {
  // 组件销毁
this.hovertip.destroy();
}
}
}

  

  通过ViewContainerRef类来管理视图,这里用到了创建组件。这个 专栏 解释的挺清楚的。这里用到了以下两个API,清除和创建。

  

Angular使用总结 --- 通过指令动态添加组件

  

  createComponent方法接受ComponentFactoty类,创建后返回的ComponentRef类,可以获取到组件实例(instance),控制组件销毁。

Angular使用总结 --- 通过指令动态添加组件

  大致思路是这样的,先获取到了HovertipComponent组件对于的componentFactory,监听鼠标移入事件,在触发事件时,通过ViewContainerRef类来创建组件,存下返回的组件componentRef(获取实例,销毁组件时需要用到),向组件实例传递tipText。监听鼠标移出事件,在事件触发时,销毁组件。

使用

  在目标元素是绑定指令,同时传递tipText即可。Angular使用总结 --- 通过指令动态添加组件

  可以正常的创建和销毁。

Angular使用总结 --- 通过指令动态添加组件

总结

  开始做的时候,主要是对这几个类比较懵,ViewContainerRef、ComponentRef、ComponentFactory、ComponentFactoryResolver等,看看源码,查查资料,总会梳理清楚的。

  参考资料:

   https://segmentfault.com/a/1190000008672478#articleHeader1

   https://segmentfault.com/a/1190000009175508

Angular使用总结 --- 通过指令动态添加组件的更多相关文章

  1. easyui 动态添加组件 要重新渲染

    做项目时动态添加组件是常有的事,easyui动态添加组件时样式会失效,这是因为这个组件没有经过 easyui的解析器解析, 比如:   <pre name="code" cl ...

  2. 使用js动态添加组件

    在文章开始之前,我想说两点 1 自己初学js,文章的内容在大神看来可能就是不值一提,但是谁都是从hello world来的,望高   手不吝指教# 2 我知道这个标题起的比较蛋疼,大家看图就能说明问题 ...

  3. vue2&period;0动态添加组件

    方法一.<template> <input type="text" v-model='componentName'> <button @click=' ...

  4. Android笔记(六十一)动态添加组件

    想要一个功能,点击按钮,可以在已有的布局上,新添加一组组件. 动态的创建组件,本质上还是创建组件,只不过是在程序中根据逻辑来创建.大致步骤是找到要创建控件的位置,然后将要创建的组件添加进去. 看代码: ...

  5. 动态添加组件(XML)

    1.利用LayoutInflater的inflate动态加载XMLmLinearLayout = (LinearLayout)findViewById(R.id.LinearLayout_ID);La ...

  6. easyui 使用jquery动态添加组件样式问题

    可以使用$.parser.parse();这个方法进行处理: 例如:   $.parser.parse(); 表示对整个页面重新渲染,渲染完就可以看到easyui原来的样式了:   var targe ...

  7. &lbrack;deviceone开发&rsqb;-动态添加组件add方法的示例

    一.简介 这个示例详细介绍ALayout的add方法的使用(原理也适用于Linearlayout),以及add上去的新ui和已有的ui如何数据交换,初学者推荐.二.效果图 三.相关下载 https:/ ...

  8. svg web拓扑更新了,支持动态添加svg组件

    版本1.0请点此 预览地址 https://svg.yaolunmao.top 如何使用 # 克隆项目 git clone https://github.com/yaolunmao/vue-webto ...

  9. unity3d动态操作组件

    利用范型,动态操作组件(添加或删除) e.AddComponent<CubeTranslate> ();//动态添加组件 Destroy (e.GetComponent<CubeTr ...

随机推荐

  1. Android引导指示层的制作 (ViewStub &plus; SharePreference)

    引导指示界面是个什么鬼东西?一张图即明了:

  2. Deep Learning 11&lowbar;深度学习UFLDL教程:数据预处理(斯坦福大学深度学习教程)

    理论知识:UFLDL数据预处理和http://www.cnblogs.com/tornadomeet/archive/2013/04/20/3033149.html 数据预处理是深度学习中非常重要的一 ...

  3. Go学习记录

    操作系统:Windows 一.下载 go官网:https://golang.org/go下载地址:https://golang.org/dl/ 二.安装 安装包有msi安装版本,以及zip压缩包版本. ...

  4. java 堆栈 静态

    所以静态变量和非静态变量的区别就在于静态变量可以用来计数,而非静态变量则不行. 理解了内存,就理解了一切,就理解了各种各样的语言.所有的语言无非都是这样:局部变量分配内存永远在栈里面,new出来的东西 ...

  5. 爬虫再探之mysql简单使用

    在爬取数据量比较大时,用EXCEL存取就不太方便了,这里简单介绍一下python操作mysql数据库的一些操作.本人也是借助别人的博客学习的这些,但是找不到原来博客链接了,就把自己的笔记写在这里,这里 ...

  6. 黑马程序员——JAVA基础之构造函数,构造代码块

    ------- android培训.java培训.期待与您交流! ---------- 构造函数特点: 1.  函数名与类名相同 2.  不用定义返回值类型 3.  不可以写return语句 构造函数 ...

  7. C&num; 控件双缓冲控制 ControlStyles 枚举详解

    ControlStyles 枚举 .NET Framework 4    指定控件的样式和行为. 此枚举有一个 FlagsAttribute 特性,通过该特性可使其成员值按位组合. 命名空间:  Sy ...

  8. 浅谈C语言中的联合体

    联合体union 当多个数据须要共享内存或者多个数据每次仅仅取其一时.能够利用联合体(union).在C Programming Language 一书中对于联合体是这么描写叙述的: 1)联合体是一个 ...

  9. SRM 447&lpar;1-250pt&comma; 1-500pt&rpar;

    DIV1 250 水题...略. DIV1 500 抽象题意:有一个图,指定其中亮点p1和p2,删掉途中其他的一些点,使得p1和p2最短路大于3. 解法:使得p1和p2最短路为2的点一定要删掉.然后, ...

  10. Problem A&colon; A &plus; B

    Problem A: A + BTime Limit: 1 Sec Memory Limit: 128 MBSubmit: 17 Solved: 10[Submit][Status][Web Boar ...