angular动态表单制作


Posted in Javascript onFebruary 23, 2018

源码:https://github.com/Karin001/ngx-dynamic-form

angular动态表单制作

动态表单使用场景

有时候我们需要一个灵活的表单,这个表单可以根据用户的选择,或者服务器返回的信息进行重新配置,比如:增加或删除一组input元素、一组select元素,等等。

在这样的情况下,如果一开始就在模板里写下所有的表单,利用一个ngif树状结构进行选择控制,程序会变得比较冗余。

这时。程序最好是能够根据用户的选择(driven by configuration)或者服务器的响应,自动生成所需要的表单。这就是动态表单要处理的业务。

组件生成的相关概念组件的两个构成

要动态生成表单,需要先理解组件是如何生成的。

一个angular组件由两部分所组成。

Wrapper

Wrapper能够与组件进行交互,当一个Wrapper初始化完成后,就已经帮我们实例化了一个组件。同时,它也负责组件的change detection,以及触发钩子函数比如ngOnInit,ngOnChanges。

View

View负责呈现渲染过后的模板,将组件的外貌展示出来,并且能够触发Wrapper的change detection。一个组件可以有多个view,每一个view可以通过调用angular提供的两个函数自行生成和销毁,这个过程不用顶层的视图参与。

组件的通常加载方式(非动态加载方式)

通常情况下,我们都是把组件内嵌到根组件或者另一个组件当中使用。嵌入的组件称为子组件,被嵌入的称为父组件。这时,当我们的子组件代码在被编译时,会生成一个组件工厂component factory(这是angular核心类ComponentFactory的一个实例),和一个hsot view,host view负责本组件在父组件视图内生成该组件的dom节点,以及生成该组件的wrapper和view。

动态加载组件

而当我们想要将一个动态组件插入某个组件视图时,则无法取得这个动态组件的实例,因为这些是非动态组件编译器做的事。

实现动态组件

angular提供了一些函数解决上面的难题,要使用这些函数我们需要注入两个对象。

constructor(
 private componentFactoryResolver: ComponentFactoryResolver,
 private viewcontainerRef: ViewContainerRef,
 ) {
  
 }

我们注入了ComponentFactoryResolver,和ViewContainerRef。

ComponentFactoryResolver上提供了一个方法(resolveComponentFactory()),该方法接收一个组件类作为参数,生成一个基于该组件类的组件工厂,也就是我们之前提到的那个组件工厂。

ViewContainerRef提供了一个方法(createComponent()),该方法接收组件工厂作为参数,在该视图中生成子组件。(我个人的理解是它处理了host view所做的事,为组件生成了wrapper和view)

实现动态表单

上文简要的介绍了实现动态组件的一些技术,现在开始思考如何做一个动态表单。

具体思路

我们想要做出一个独立的动态表单模块,当我们想要使用动态表单时,只需简单引入这个模块,稍加配置即可使用。

我们希望这个模块做好了后,在顶层使用者的角度会是这样一个工作流程:

angular动态表单制作

我们可以很容易的做出一个具有输入属性的组件,问题的核心在于这个组件是如何根据输入属性生成我们想要的表单。

也就是说,是它自己调用ComponentFactoryResolver和ViewContainerRef进行组件的动态生成,还是交给别人处理。

下图是实现思路:

angular动态表单制作

实际上我们把动态表单拆分成了一个个小的动态组件(不预先加载),由外层的一个组件充当一个容器,所有的动态组件都会在里面进行生成和销毁,他们共同组成了一个动态表单。调用ComponentFactoryResolver和ViewContainerRef生成组件的的这部分逻辑没有集成在外层容器中,而是交给了一个自定义的指令和ng-container。因为指令没有视图,他通过注入ViewContainerRef获取到的是宿主的视图容器。由于ng-container不会被渲染,所以获取到的视图容器就是外层组件容器的视图容器。

这么处理的好处就是不需要由外层组件统一对各个拆分的动态组件进行管理,相当于是由动态组件自己进行管理。

外层组件容器大概会是下面这样:

<form>
 <ng-container *ngFor="let config of configs" [自定义指令] >
 </ng-container>
</form>
configs是用户的配置数据,自定义指令寄宿在ng-container中,根据config渲染出各自的动态组件,而ng-container是透明的。

看一下代码目录结构,最后会是这个样子

angular动态表单制作

以上就是大体的实现思路了,具体还有许多细节可以关注文章开头提到的那两篇文章,讲的很详细。

Javascript 相关文章推荐
用javascript实现的支持lrc歌词的播放器
May 17 Javascript
jquery 与NVelocity 产生冲突的解决方法
Jun 13 Javascript
详解JavaScript函数绑定
Aug 18 Javascript
JavaScript的Polymer框架中dom-repeat与VM的相关操作
Jul 29 Javascript
javascript结合Flexbox简单实现滑动拼图游戏
Feb 18 Javascript
浅谈jQuery中ajaxPrefilter的应用
Aug 01 Javascript
JavaScript数组迭代方法
Mar 03 Javascript
微信小程序将字符串生成二维码图片的操作方法
Jul 17 Javascript
vue2.0 element-ui中el-select选择器无法显示选中的内容(解决方法)
Aug 24 Javascript
vue实现输入框的模糊查询的示例代码(节流函数的应用场景)
Sep 01 Javascript
Layer.js实现表格溢出内容省略号显示,悬停显示全部的方法
Sep 16 Javascript
微信小程序swiper组件实现抖音翻页切换视频功能的实例代码
Jun 24 Javascript
angularjs中$http异步上传Excel文件方法
Feb 23 #Javascript
浅谈vuejs实现数据驱动视图原理
Feb 23 #Javascript
Vue父组件调用子组件事件方法
Feb 23 #Javascript
vue实现密码显示隐藏切换功能
Feb 23 #Javascript
对vue.js中this.$emit的深入理解
Feb 23 #Javascript
基于vue.js中事件修饰符.self的用法(详解)
Feb 23 #Javascript
vue.js2.0点击获取自己的属性和jquery方法
Feb 23 #jQuery
You might like
先进的自动咖啡技术,真的可以取代咖啡师吗?
2021/03/06 冲泡冲煮
那些年一起学习的PHP(二)
2012/03/21 PHP
php操作xml入门之xml基本介绍及xml标签元素
2015/01/23 PHP
PHP+AJAX实现投票功能的方法
2015/09/28 PHP
php 在字符串指定位置插入新字符的简单实现
2016/06/28 PHP
PHP实现类似题库抽题效果
2018/08/16 PHP
在thinkphp5.0路径中实现去除index.php的方式
2019/10/16 PHP
PHP实现简单登录界面
2019/10/23 PHP
JavaScript创建命名空间(namespace)的最简实现
2007/12/11 Javascript
JavaScript 解析Json字符串的性能比较分析代码
2009/12/16 Javascript
jQuery操作复选框(CheckBox)的取值赋值实现代码
2017/01/10 Javascript
Vue数据驱动模拟实现4
2017/01/12 Javascript
JS实现定时任务每隔N秒请求后台setInterval定时和ajax请求问题
2017/10/15 Javascript
vue.js将时间戳转化为日期格式的实现代码
2018/06/05 Javascript
微信小程序学习笔记之函数定义、页面渲染图文详解
2019/03/28 Javascript
基于Vue的商品主图放大镜方案详解
2019/09/19 Javascript
Node.js API详解之 vm模块用法实例分析
2020/05/27 Javascript
[51:29]完美世界DOTA2联赛循环赛 Matador vs Forest BO2第一场 11.05
2020/11/05 DOTA
在Python中使用__slots__方法的详细教程
2015/04/28 Python
python操作ie登陆土豆网的方法
2015/05/09 Python
python 打印出所有的对象/模块的属性(实例代码)
2016/09/11 Python
pandas 对日期类型数据的处理方法详解
2019/08/08 Python
对Pytorch中nn.ModuleList 和 nn.Sequential详解
2019/08/18 Python
深入了解Python enumerate和zip
2020/07/16 Python
python 服务器运行代码报错ModuleNotFoundError的解决办法
2020/09/16 Python
HTML5 localStorage使用总结
2017/02/22 HTML / CSS
求职信的要素有哪些呢
2013/12/26 职场文书
工商管理专业大学生职业生涯规划范文
2014/03/09 职场文书
人民调解员先进事迹材料
2014/05/08 职场文书
学校法制宣传月活动总结
2014/07/03 职场文书
法人委托书范本
2014/09/15 职场文书
通报表扬范文
2015/01/17 职场文书
先进工作者个人总结
2015/02/15 职场文书
2015年幼儿园后勤工作总结
2015/04/25 职场文书
导游词之平津战役纪念馆
2019/11/04 职场文书
Python socket如何解析HTTP请求内容
2022/02/12 Python