动态创建Angular组件实现popup弹窗功能
发布时间 - 2026-01-11 03:16:01 点击率:次起步: 直接使用ngIf

把弹窗的DOM直接放在页面底下隐藏,通过ngIf这样的指令控制其显示。
改进: 封装成angular模块,通过服务控制其显示
直接使用ngIf的话,让人不爽的地方就在于不够通用,每个页面都得加DOM。改进的话可以把比较通用的一些DOM封装成组件,统一添加到全局页面中,并将显示的控制交给一个angular服务来控制其显示。
比如定义了两个组件(DialogComponent, AlertComponent),将他们都添加到AppComponent下,然后提供一个PopupService来控制组件的显示,并支持传递参数进去。
仅通过控制显示的方式仍不够通用且存在耦合
将弹窗组件封装然后使用服务来控制显示的方法看上去已经比较通用了,不过还存在两个尴尬的问题:
- 仍然需要在页面的某个地方放置一个弹窗组件,比如叫做PopupComponent,此组件负责渲染出默认隐藏的一些通用弹窗子组件,才能进行显示控制实现弹窗能力。
- 如果想要弹出一个自定义窗口的话就只能回到最上面另外写DOM放到需要弹出自定义弹窗的位置上,或者将自定义的标签通过innerHtml指令传入(富文本方式)。
由此可见这样的弹窗能力并没有做到非常通用,且必须手动放置弹窗插座(姑且这么叫)以致多了一处耦合。
动态创建弹窗
最理想的方式应该是: 在想要弹个窗口出来时直接一行代码把窗口弹出来,不用事先在哪里先把这个弹窗写好(或者说这一步不应该由弹窗控件的使用者来做,弹窗控件应该要自动完成这件事)。
而这一能力就涉及到angular的动态创建组件的能力了。
官网给出的用法
angular的官方文档中就有关于动态创建组件的用法。不过其使用的是ViewContainerRef服务,此服务提供了createComponent方法来在指定的视图容器下动态创建一个组件出来。
不过ViewContainerRef的尴尬点是只能在具体的指令、组件中使用,也就是说,必须告诉它打算在哪个地方创建新组建,这不还是需要实现创建好一个“弹窗插座”出来,才可以在这个“插座”中动态创建组件。
那有什么办法可以不给定视图容器而创建出组建来,通俗地讲问题就是: 不是在指令或者组件中创建组件,而是在服务中创建出组件,还要让这个组件显示到页面上去。
组建工厂——组件真正的创建者
在组件中创建组件的核心代码分两步:
创建组件工厂
let componentFactory = this.componentFactoryResolver.resolveComponentFactory(待创建组件);
把工厂提供给容器创建出组件
let componentRef = viewContainerRef.createComponent(componentFactory);
现在的问题在于,在服务中得不到viewContainerRef,工厂倒是能创建成功。
其实有工厂了已经足够了,查看componentFactory提供的成员里面包含了一个create方法,顾名思义这应该就是用来创建组件的了。
create方法有个必选参数类型为Injector,顾名思义就是注入器,即这个创建的组件打算注入些什么服务进去,暴力点直接写null也没问题。
直接使用工厂创建组件返回的同样是一个ComponentRef类型的引用,可见此时组件确实是创建出来了,但是还没有将其插入到视图中去。此时可以再暴力一点,直接用原生DOM操作插入到body标签的末尾去:
window.document.body.appendChild(
this.getComponentRootNode(componentRef)
);
this.appRef.attachView(componentRef); // 注入ApplicationRef服务后使用
// ...
private getComponentRootNode(componentRef: ComponentRef<any>): HTMLElement {
return (componentRef.hostView as EmbeddedViewRef<any>).rootNodes[0] as HTMLElement;
}
// ...
此办法是笔者从Material2的茫茫源代码中找到的,Google自己都直接这么插,那就放心使用了。这里不得不赞叹Material2中Dialog模块的实现,实在是有够复杂。
总结
本文主要在讲思路,扯到最后才开始要进入主题来动态创建组件,不过仅仅是创建出组件并添加到DOM中去还只是第一步,一个健壮的弹窗模块(Material2那样的)还得有一套完善的交互能力,比如弹出和关闭时的订阅和传值,这些就要通过注入服务到组件中来实现了,限于篇幅将在下一篇文章中回归实际实现一个通过动态创建组件实现的弹窗模块出来。
以上所述是小编给大家介绍的动态创建Angular组件实现popup弹窗功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!
# angular
# 动态创建组件
# popup弹窗
# 详解Angular 4.x 动态创建组件
# Angularjs 创建可复用组件实例代码
# Angular 4根据组件名称动态创建出组件的方法教程
# Angular7创建项目、组件、服务以及服务的使用
# 如何在Angular应用中创建包含组件方法示例
# 弹出
# 自定义
# 是在
# 顾名思义
# 中去
# 小编
# 的是
# 是一个
# 这一
# 让人
# 还没有
# 放在
# 有个
# 在这个
# 是有
# 那就
# 也没
# 在此
# 将在
# 将其
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
用v-html解决Vue.js渲染中html标签不被解析的问题
悟空识字如何进行跟读录音_悟空识字开启麦克风权限与录音
详解jQuery中的事件
如何解决hover在ie6中的兼容性问题
如何快速查询网站的真实建站时间?
小米17系列还有一款新机?主打6.9英寸大直屏和旗舰级影像
最好的网站制作公司,网购哪个网站口碑最好,推荐几个?谢谢?
Laravel如何设置定时任务(Cron Job)_Laravel调度器与任务计划配置
EditPlus中的正则表达式 实战(2)
详解免费开源的.NET多类型文件解压缩组件SharpZipLib(.NET组件介绍之七)
Android Socket接口实现即时通讯实例代码
免费的流程图制作网站有哪些,2025年教师初级职称申报网上流程?
php打包exe后无法访问网络共享_共享权限设置方法【教程】
详解Huffman编码算法之Java实现
重庆市网站制作公司,重庆招聘网站哪个好?
Laravel如何配置和使用缓存?(Redis代码示例)
Laravel Eloquent访问器与修改器是什么_Laravel Accessors & Mutators数据处理技巧
C++用Dijkstra(迪杰斯特拉)算法求最短路径
关于BootStrap modal 在IOS9中不能弹出的解决方法(IOS 9 bootstrap modal ios 9 noticework)
Python结构化数据采集_字段抽取解析【教程】
php读取心率传感器数据怎么弄_php获取max30100的心率值【指南】
PythonWeb开发入门教程_Flask快速构建Web应用
在centOS 7安装mysql 5.7的详细教程
西安专业网站制作公司有哪些,陕西省建行官方网站?
5种Android数据存储方式汇总
如何用已有域名快速搭建网站?
如何用花生壳三步快速搭建专属网站?
JS中对数组元素进行增删改移的方法总结
海南网站制作公司有哪些,海口网是哪家的?
如何在云主机快速搭建网站站点?
音响网站制作视频教程,隆霸音响官方网站?
如何用狗爹虚拟主机快速搭建网站?
专业企业网站设计制作公司,如何理解商贸企业的统一配送和分销网络建设?
Laravel如何使用Seeder填充数据_Laravel模型工厂Factory批量生成测试数据【方法】
Laravel如何使用Scope本地作用域_Laravel模型常用查询逻辑封装技巧【手册】
东莞专业网站制作公司有哪些,东莞招聘网站哪个好?
宙斯浏览器文件分类查看教程 快速筛选视频文档与图片方法
Win11摄像头无法使用怎么办_Win11相机隐私权限开启教程【详解】
如何在阿里云服务器自主搭建网站?
如何在浏览器中启用Flash_2025年继续使用Flash Player的方法【过时】
Laravel中DTO是什么概念_在Laravel项目中使用数据传输对象(DTO)
Laravel PHP版本要求一览_Laravel各版本环境要求对照
深圳网站制作的公司有哪些,dido官方网站?
使用Dockerfile构建java web环境
CSS3怎么给轮播图加过渡动画_transition加transform实现【技巧】
Laravel如何配置.env文件管理环境变量_Laravel环境变量使用与安全管理
Laravel Livewire是什么_使用Laravel Livewire构建动态前端界面
Python高阶函数应用_函数作为参数说明【指导】
浅析上传头像示例及其注意事项
标准网站视频模板制作软件,现在有哪个网站的视频编辑素材最齐全的,背景音乐、音效等?

