Angular通過指令動態(tài)添加組件問題
之前自己寫的公共組件,都是會先引入,需要調(diào)起的時候再通過service控制公共組件狀態(tài)、值、回調(diào)函數(shù)什么的。但是有一些場景不適合這種方式,還是動態(tài)添加組件更加好。通過寫過的一個小組件來總結(jié)下。
創(chuàng)建組件
場景:鼠標(biāo)移動到圖標(biāo)上時,展示解釋性的說明文字。那就需要創(chuàng)建一個普通的tooltip組件。如下:
<aside class="hover-tip-wrapper">
<span>{{tipText}}</span>
</aside>
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這個配置項(xiàng)是做什么的呢?看源碼注釋,大概意思就是:Angular會為此配置項(xiàng)中的組件創(chuàng)建一個ComponentFactory,并存放在ComponentFactoryResolver中。動態(tài)添加組件時,需要用到組件工廠,所以此配置是必不可少的。

創(chuàng)建指令
通過指令為目標(biāo)元素綁定事件,控制創(chuàng)建組件、傳遞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
) {
// 獲取對應(yīng)的組件工廠
this.factory = this.resolver.resolveComponentFactory(HovertipComponent);
}
@Input('appHovertip') tipText: string;
// 綁定鼠標(biāo)移入的事件
@HostListener('mouseenter') onmouseenter() {
// 清空所有的view
this.viewContainer.clear();
// 創(chuàng)建組件
this.hovertip = this.viewContainer.createComponent(this.factory);
// 向組件實(shí)例傳遞參數(shù)
this.hovertip.instance.tipText = this.tipText;
}
// 綁定鼠標(biāo)移出時的事件
@HostListener('mouseleave') onmouseleave() {
if (this.hovertip) {
// 組件銷毀
this.hovertip.destroy();
}
}
}
通過ViewContainerRef類來管理視圖,這里用到了創(chuàng)建組件。這個 專欄 解釋的挺清楚的。這里用到了以下兩個API,清除和創(chuàng)建。

createComponent方法接受ComponentFactoty類,創(chuàng)建后返回的ComponentRef類,可以獲取到組件實(shí)例(instance),控制組件銷毀。

大致思路是這樣的,先獲取到了HovertipComponent組件對于的componentFactory,監(jiān)聽鼠標(biāo)移入事件,在觸發(fā)事件時,通過ViewContainerRef類來創(chuàng)建組件,存下返回的組件componentRef(獲取實(shí)例,銷毀組件時需要用到),向組件實(shí)例傳遞tipText。監(jiān)聽鼠標(biāo)移出事件,在事件觸發(fā)時,銷毀組件。
使用
在目標(biāo)元素是綁定指令,同時傳遞tipText即可。

可以正常的創(chuàng)建和銷毀。

總結(jié)
開始做的時候,主要是對這幾個類比較懵,ViewContainerRef、ComponentRef、ComponentFactory、ComponentFactoryResolver等,看看源碼,查查資料,總會梳理清楚的。
參考資料:
相關(guān)文章
AngularJS基礎(chǔ) ng-submit 指令簡單示例
本文主要介紹AngularJS ng-submit 指令,這里對ng-submit 指令的基礎(chǔ)資料做了詳細(xì)介紹整理,并附有代碼示例,有需要的小伙伴可以參考下2016-08-08
詳解Angular數(shù)據(jù)綁定及其實(shí)現(xiàn)方式
數(shù)據(jù)綁定是將應(yīng)用程序UI或用戶界面綁定到模型的機(jī)制。使用數(shù)據(jù)綁定,用戶將能夠使用瀏覽器來操縱網(wǎng)站上存在的元素。2021-05-05
angula中使用iframe點(diǎn)擊后不執(zhí)行變更檢測的問題
這篇文章主要介紹了angula中使用iframe點(diǎn)擊后不執(zhí)行變更檢測問題,本文給大家分享解決方案,通過實(shí)例代碼給的大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-05-05
Angular使用過濾器uppercase/lowercase實(shí)現(xiàn)字母大小寫轉(zhuǎn)換功能示例
這篇文章主要介紹了Angular使用過濾器uppercase/lowercase實(shí)現(xiàn)字母大小寫轉(zhuǎn)換功能,涉及AngularJS過濾器針對字符串轉(zhuǎn)換的簡單使用技巧,需要的朋友可以參考下2018-03-03
關(guān)于angular表單動態(tài)驗(yàn)證的一種新思路分享
在Angular?中不管是模板驅(qū)動表單還是響應(yīng)式表單,對于動態(tài)創(chuàng)建表單的支持都很好,下面這篇文章主要給大家介紹了關(guān)于angular表單動態(tài)驗(yàn)證的一種新思路,需要的朋友可以參考下2022-03-03
AngularJS自定義過濾器用法經(jīng)典實(shí)例總結(jié)
這篇文章主要介紹了AngularJS自定義過濾器用法,結(jié)合實(shí)例形式總結(jié)分析了AngularJS自定義過濾器進(jìn)行包含、替換、篩選、過濾、排序等操作相關(guān)實(shí)現(xiàn)技巧與注意事項(xiàng),需要的朋友可以參考下2018-05-05
淺談angular4實(shí)際項(xiàng)目搭建總結(jié)
本篇文章主要介紹了淺談angular4實(shí)際項(xiàng)目搭建總結(jié),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-12-12

