Angular通过指令动态添加组件问题

网友投稿 299 2023-01-26


Angular通过指令动态添加组件问题

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

创建组件

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

{{tipText}}

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() {

}

}

.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;

}

}

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

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

entryComponents: [HovertipComponent],

declarations: [HovertipComponent, HovertipDirective]

那entryComponents这个配置项是做什么的呢?看源码注释,大概意思就是:Angular会为此http://配置项中的组件创建一个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;

public factory: ComponentFactory;

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://jb51.net/article/114683.htm

https://jb51.net/article/112123.htm


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:好用的共享文件系统(好用的文件共享软件)
下一篇:java根据网络地址保存图片的方法
相关文章

 发表评论

暂时没有评论,来抢沙发吧~