起步: 直接使用ngIf

把弹窗的DOM直接放在页面底下隐藏,通过ngIf这样的指令控制其显示。
改进: 封装成angular模块,通过服务控制其显示
直接使用ngIf的话,让人不爽的地方就在于不够通用,每个页面都得加DOM。改进的话可以把比较通用的一些DOM封装成组件,统一添加到全局页面中,并将显示的控制交给一个angular服务来控制其显示。
比如定义了两个组件(DialogComponent, AlertComponent),将他们都添加到AppComponent下,然后提供一个PopupService来控制组件的显示,并支持传递参数进去。
仅通过控制显示的方式仍不够通用且存在耦合
将弹窗组件封装然后使用服务来控制显示的方法看上去已经比较通用了,不过还存在两个尴尬的问题:
由此可见这样的弹窗能力并没有做到非常通用,且必须手动放置弹窗插座(姑且这么叫)以致多了一处耦合。
动态创建弹窗
最理想的方式应该是: 在想要弹个窗口出来时直接一行代码把窗口弹出来,不用事先在哪里先把这个弹窗写好(或者说这一步不应该由弹窗控件的使用者来做,弹窗控件应该要自动完成这件事)。
而这一能力就涉及到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应用中创建包含组件方法示例
# 弹出
# 自定义
# 是在
# 顾名思义
# 中去
# 小编
# 的是
# 是一个
# 这一
# 让人
# 还没有
# 放在
# 有个
# 在这个
# 是有
# 那就
# 也没
# 在此
# 将在
# 将其
相关文章:
学生网站制作软件,一个12岁的学生写小说,应该去什么样的网站?
如何快速使用云服务器搭建个人网站?
如何通过VPS建站实现广告与增值服务盈利?
网站建设制作需要多少钱费用,自己做一个网站要多少钱,模板一般多少钱?
家族网站制作贴纸教程视频,用豆子做粘帖画怎么制作?
制作国外网站的软件,国外有哪些比较优质的网站推荐?
Android使用GridView实现日历的简单功能
海南网站制作公司有哪些,海口网是哪家的?
如何在云主机快速搭建网站站点?
建站之星导航配置指南:自助建站与SEO优化全解析
网页制作模板网站推荐,网页设计海报之类的素材哪里好?
建站主机服务器选购指南:轻量应用与VPS配置解析
如何选择靠谱的建站公司加盟品牌?
智能起名网站制作软件有哪些,制作logo的软件?
IOS倒计时设置UIButton标题title的抖动问题
如何选择高效便捷的WAP商城建站系统?
微课制作网站有哪些,微课网怎么进?
c# Task.Yield 的作用是什么 它和Task.Delay(1)有区别吗
C++时间戳转换成日期时间的步骤和示例代码
早安海报制作网站推荐大全,企业早安海报怎么每天更换?
如何在香港服务器上快速搭建免备案网站?
网站制作服务平台,有什么网站可以发布本地服务信息?
如何配置FTP站点权限与安全设置?
广州营销型建站服务商推荐:技术优势与SEO优化解析
常州自助建站:操作简便模板丰富,企业个人快速搭建网站
网站广告牌制作方法,街上的广告牌,横幅,用PS还是其他软件做的?
微信小程序 五星评分(包括半颗星评分)实例代码
如何高效配置IIS服务器搭建网站?
宝盒自助建站智能生成技巧:SEO优化与关键词设置指南
如何批量查询域名的建站时间记录?
C++ static_cast和dynamic_cast区别_C++静态转换与动态类型安全转换
如何使用Golang安装API文档生成工具_快速生成接口文档
贸易公司网站制作流程,出口贸易网站设计怎么做?
如何用5美元大硬盘VPS安全高效搭建个人网站?
魔毅自助建站系统:模板定制与SEO优化一键生成指南
网站按钮制作软件,如何实现网页中按钮的自动点击?
单页制作网站有哪些,朋友给我发了一个单页网站,我应该怎么修改才能把他变成自己的呢,请求高手指点迷津?
建站之星在线客服如何快速接入解答?
香港服务器WordPress建站指南:SEO优化与高效部署策略
,怎么在广州志愿者网站注册?
如何实现建站之星域名转发设置?
专业网站建设制作报价,网页设计制作要考什么证?
网站制作哪家好,cc、.co、.cm哪个域名更适合做网站?
网站制作软件免费下载安装,有哪些免费下载的软件网站?
建站上传速度慢?如何优化加速网站加载效率?
公司网站制作价格怎么算,公司办个官网需要多少钱?
网站设计制作公司地址,网站建设比较好的公司都有哪些?
建站三合一如何选?哪家性价比更高?
官网自助建站平台指南:在线制作、快速建站与模板选择全解析
电影网站制作价格表,那些提供免费电影的网站,他们是怎么盈利的?
*请认真填写需求信息,我们会在24小时内与您取得联系。