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 继承机制的实现
Aug 12 Javascript
javascript 密码强度验证规则、打分、验证(给出前端代码,后端代码可根据强度规则翻译)
May 18 Javascript
Javascript学习笔记-详解in运算符
Sep 13 Javascript
formStorage 基于jquery的一个插件(存储表单中元素的状态到本地)
Jan 20 Javascript
Javascript绝句欣赏 一些经典的js代码
Feb 22 Javascript
理解JavaScript事件对象
Jan 25 Javascript
Angularjs中UI Router全攻略
Jan 29 Javascript
jQuery使用$获取对象后检查该对象是否存在的实现方法
Sep 04 Javascript
详解Vue组件之间的数据通信实例
Jun 17 Javascript
Vue 样式切换及三元判断样式关联操作
Aug 09 Javascript
vue组件实现移动端九宫格转盘抽奖
Oct 16 Javascript
基于react项目打包css引用路径错误解决方案
Oct 28 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
简单介绍下 PHP5 中引入的 MYSQLI的用途
2007/03/19 PHP
PHP中__get()和__set()的用法实例详解
2013/06/04 PHP
php遍历目录输出目录及其下的所有文件示例
2014/01/27 PHP
php实现的rc4加密解密类定义与用法示例
2018/08/16 PHP
laravel 实现设置时区的简单方法
2019/10/10 PHP
php数组函数array_push()、array_pop()及array_shift()简单用法示例
2020/01/26 PHP
javascript 浏览器判断 绑定事件 arguments 转换数组 数组遍历
2009/07/06 Javascript
javascript针对DOM的应用实例(一)
2012/04/15 Javascript
jQuery基础框架浅入剖析
2012/12/27 Javascript
js兼容pc端浏览器并有多种弹出小提示的手机端浮层控件实例
2015/04/29 Javascript
Bootstrap每天必学之按钮
2015/11/26 Javascript
js使用cookie记录用户名的方法
2015/11/26 Javascript
ionic 上拉菜单(ActionSheet)实例代码
2016/06/06 Javascript
微信小程序删除处理详解
2017/08/16 Javascript
Vue-Router2.X多种路由实现方式总结
2018/02/09 Javascript
Angular @HostBinding()和@HostListener()用法
2018/03/05 Javascript
关于vue-cli3打包代码后白屏的解决方案
2020/09/02 Javascript
jQuery实现回到顶部效果
2020/10/19 jQuery
uniapp实现可以左右滑动导航栏
2020/10/21 Javascript
python实现rsa加密实例详解
2017/07/19 Python
Django中Forms的使用代码解析
2018/02/10 Python
python opencv旋转图像(保持图像不被裁减)
2018/07/26 Python
python3+selenium自动化测试框架详解
2019/03/17 Python
python程序快速缩进多行代码方法总结
2019/06/23 Python
Python3.x+迅雷x 自动下载高分电影的实现方法
2020/01/12 Python
python使用Geany编辑器配置方法
2020/02/21 Python
Python中使用Selenium环境安装的方法步骤
2021/02/22 Python
香港唯港荟酒店预订:Hotel ICON
2018/03/27 全球购物
《桃花心木》教学反思
2014/02/17 职场文书
幼儿园教学随笔感言
2014/02/23 职场文书
《春到梅花山》教学反思
2014/04/16 职场文书
办公室文员工作自我鉴定
2014/09/19 职场文书
民间个人借款协议书
2014/09/30 职场文书
村主任群众路线教育实践活动个人对照检查材料思想汇报
2014/10/01 职场文书
2019年大学推荐信
2019/06/24 职场文书
python利用pandas分析学生期末成绩实例代码
2021/07/09 Python