咨询热线:15899869609 联系人:吴平凡 地址:西藏自治省拉萨市西郊安居园一区五排九号
Angular使用总结 --- 通过指令动态添加组件
来源:oebet2 发布时间:2019-12-03 点击量:441
之前自己写的公共组件,都是会先引入,需要调起的时候再通过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: 0; width: 0; 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中。动态添加组件时,需要用到组件工厂,所以此配置是必不可少的。
创建指令
通过指令为目标元素绑定事件,控制创建组件、传递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,清除和创建。
createComponent方法接受ComponentFactoty类,创建后返回的ComponentRef类,可以获取到组件实例(instance),控制组件销毁。
大致思路是这样的,先获取到了HovertipComponent组件对于的componentFactory,监听鼠标移入事件,在触发事件时,通过ViewContainerRef类来创建组件,存下返回的组件componentRef(获取实例,销毁组件时需要用到),向组件实例传递tipText。监听鼠标移出事件,在事件触发时,销毁组件。
使用
在目标元素是绑定指令,同时传递tipText即可。
可以正常的创建和销毁。
总结
开始做的时候,主要是对这几个类比较懵,ViewContainerRef、ComponentRef、ComponentFactory、ComponentFactoryResolver等,看看源码,查查资料,总会梳理清楚的。
参考资料:
https://segmentfault.com/a/1190000008672478#articleHeader1
https://segmentfault.com/a/1190000009175508
相关产品
-
7. 赵广印:你是个聪明、活泼、可爱的孩子。课堂上总能看到你高高举起的小手,上课思维活跃,积极动脑、踊跃发言,你做数学题总是又快又对,小脑袋非常灵活,语言表达能力也较强,经常抢着上来为大家讲故事。希望你以后加强小手的锻炼,让你的小手变得更灵活,成为一名心灵手巧的好孩子,我们一起加油吧!
-
中新社广州1月16日电 (郭军 骆燕容)记者从16日召开的广州地区台商迎春联谊会上解到,2013年,广州市新增台资项目35宗,吸引台资投资总额1.5亿美元,穗台贸易总额达36亿美元。两地之间的交流往来也更加热络,去年穗台交流项目超过450个,交流人数达3000多人次。
-
目前绝大多数的电竞游戏赛事都是不盈利的,大多数都是开发商从游戏收入中拨出一部分专门用于赛事运营,这种模式在游戏表现良好的时候可以促进参与度、提高收入,但也很容易在表现不好的时候给开发商的经济状况雪上加霜。
-
其中,日本东京都青梅市出现了观测史上最多的每小时107.5毫米的暴雨纪录。日本静冈县伊豆市和东京都八丈町也出现了史上8月最多的每小时86.0毫米的强降雨。
-
【游侠导读】最近,一位分析师在接受采访时表示,主机的独占游戏已经不再像过去那么重要。他认为游戏公司已经不再那么需要第一方游戏的支持了。
-
中新网9月16日电 据外媒报道,飓风“艾尔玛”侵袭美洲,截至15日早晨已经造成82人死亡。尽管飓风已经过去5天,但美国佛州超过150万人无电可用,陷入高温热浪的困境。
-
细心观察可以发现,曾有着“国民闺女”称号的关晓彤已经长大,戏路逐渐拓宽。在近日热播的《九州天空城》中,她和张若昀所饰角色在剧中的虐恋引发网友热议,“不是强抱就是喂饭,虐单身狗!”
-
所以,想要保持在1~2 小时内专注地做一件事情,你首先得保证这件事情是可控的,不能远远超出你自己已有的水平,硬逼自己去挑战一些不可能的事情,只会是自欺欺人而已。
热点资讯
- 苹果收购丹麦计算机视觉公司Spektral2019-11-17
- [天猫超市]高露洁光感劲白牙膏120g×5支聚划算29.9元2019-12-01
- 跳跃表2019-11-06
- 都都股份荣获挖贝“2018年度数字营销领军企业”奖项2019-11-14
- 油价暴跌4%dailyfx黄金、原油日内走势分析2019-11-29
- Facebook已经大量使用外部应用程序来收集隐私_IT新闻,比如约会2019-06-26
- 轻盈舒适/型男必备,啄木鸟/红豆修身直筒休闲西裤59.9元2019-11-13
- 黄杨盆景的制作栽培及其养护管理技术2019-11-08