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 相关文章推荐
js的event详解。
Sep 06 Javascript
javascript中的location用法简单介绍
Mar 07 Javascript
javascript完美拖拽的实现方法
Sep 29 Javascript
jQuery基础语法实例入门
Dec 23 Javascript
bootstrap table实现点击翻页功能 可记录上下页选中的行
Sep 28 Javascript
使用ngrok+express解决本地环境中微信接口调试问题
Feb 26 Javascript
JS中利用FileReader实现上传图片前本地预览功能
Mar 02 Javascript
setTimeout时间设置为0详细解析
Mar 13 Javascript
vuex 解决报错this.$store.commit is not a function的方法
Dec 17 Javascript
angular6的table组件开发的实现示例
Dec 26 Javascript
如何利用javascript接收json信息并进行处理
Aug 06 Javascript
原生js中运算符及流程控制示例详解
Jan 05 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
深入apache host的配置详解
2013/06/09 PHP
php技术实现加载字体并保存成图片
2015/07/27 PHP
PHP API接口必备之输出json格式数据示例代码
2017/06/27 PHP
PHP基于SPL实现的迭代器模式示例
2018/04/22 PHP
php实现微信公众平台发红包功能
2018/06/14 PHP
Thinkphp页面跳转设置跳转等待时间的操作
2019/10/16 PHP
PHP中abstract(抽象)、final(最终)和static(静态)原理与用法详解
2020/06/05 PHP
用原生JS获取CLASS对象(很简单实用)
2014/10/15 Javascript
JavaScript获取中英文混合字符串长度的方法示例
2017/02/04 Javascript
关于foreach循环中遇到的问题小结
2017/05/08 Javascript
详解在vue-cli中使用路由
2017/09/25 Javascript
使用vuex缓存数据并优化自己的vuex-cache
2018/05/30 Javascript
Bootstrap 按钮样式与使用代码详解
2018/12/09 Javascript
详解VUE前端按钮权限控制
2019/04/26 Javascript
JavaScript RegExp 对象用法详解
2019/09/24 Javascript
jQuery 隐藏/显示效果函数用法实例分析
2020/05/20 jQuery
vue-cli打包后本地运行dist文件中的index.html操作
2020/08/12 Javascript
python计算N天之后日期的方法
2015/03/31 Python
Python 数据结构之旋转链表
2017/02/25 Python
Python单例模式的两种实现方法
2017/08/14 Python
详解Python 数据库的Connection、Cursor两大对象
2018/06/25 Python
python3实现点餐系统
2019/01/24 Python
Python代码使用 Pyftpdlib实现FTP服务器功能
2019/07/22 Python
python实现同一局域网下传输图片
2020/03/20 Python
一款基于css3麻将筛子3D翻转特效的实例教程
2014/12/31 HTML / CSS
音乐教学随笔感言
2014/02/19 职场文书
倡议书格式
2014/04/14 职场文书
软件售后服务承诺书
2014/05/21 职场文书
正科级干部考察材料
2014/05/29 职场文书
商业街策划方案
2014/05/31 职场文书
高中同学会活动方案
2014/08/14 职场文书
2014年重阳节活动策划方案书
2014/09/16 职场文书
大学生暑期社会实践证明范本
2014/10/24 职场文书
2016年过年放假安排通知
2015/08/18 职场文书
少先大队干部竞选稿
2015/11/20 职场文书
clear 万能清除浮动(clearfix:after)
2023/05/21 HTML / CSS