完成功能
这是一种支持多种元素的表单,包括下拉框,编辑器,日期选择器,颜色选择器等。
Angular Schema Form是分schema,form,data三块Json去定义表单。在controller里面,schema定义了数据结构,form定义了UI,model绑定了用户的输入。在html中使用统一的写法,使用ng-schema,ng-form与ng-model指令分别绑定,最后可呈现出不同的表单。
环境配置
- 先通过npm下载项目,使用指令
npm install angular-schema-form,找到项目中的dist文件夹,拿到压缩文件bootstrap-decorator.min.js与schema-form.min.js。 - 把压缩文件
bootstrap-decorator.min.js与schema-form.min.js放入项目alogic-itportal-web的lib文件夹下。压缩文件放在lib文件夹下将在发布时保持原有格式,不会被压缩。 - 参考angular-schema-form的用户手册,需要引入其他js文件,https://github.com/json-schema-form/angular-schema-form, 且需要按照一定的顺序加载,需要按照以下顺序:
angular.min.js, angular-sanitize.min.js, tv4.js ,ObjectPath.js,schema-form.min.js,bootstrap-decorator.min.js。 - 在使用到表单的入口,manage.js与app.js中分别载入schema-form模块,
var app = angular.module('app', ['schemaForm','jscross', 'ui.router', 'slick', 'pasp.ui']);。
在itportal中的应用
在itportal的manage入口,实现了用户/岗位/机构/团队的新建以及编辑更新的功能,这里大量使用了表单,下面用新建团队作为例子,分directive/controller/tpl三部分来说明schema-form的使用方法。
directive
1 | jscross.widget('newTeam', { |
分别绑定了模板和控制器,没有太多需要解释。
controller中的form
controller中的form定义,form是定义了UI,这里是说在表单中会显示有三个元素id,name和note,像name这样没有附加其他属性的,就是最基本的输入框,placeholder是显示在输入框的提示语,在定义id的时候,要判断id是否已占用,这里需要到服务器进行异步验证。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30$scope.form = [{
'key': 'id',
'placeholder': '字母数字特殊字符下划线的组合,长度大于3小于16',
'$asyncValidators': {
IdAlreadyTaken: function(value) {
var deferred = $q.defer(); //通过$q服务注册一个延迟对象deffered
if(value != undefined) {
var IdOkcallback = function(data) {
deferred.resolve();
}
var IdExistCallback = function(data) {
deferred.reject();
}
team.IdCheck({
id: value
}, IdOkcallback, IdExistCallback);
}
return deferred.promise; //promise返回当前任务的完成结果
}
},
'validationMessage':{
'IdAlreadyTaken': 'ID已经被注册!'
}
},
'name', {
'key': 'note',
'type': 'textarea',
'placeholder': '简单介绍你的团队吧'
}
];
异步校验
$q是Angular的一种内置服务,它可以使你异步地执行函数,并可以获取到函数的返回值。
deferred.resolve(value)成功解决(resolve)了其派生的promise。参数value将来会被用作promise.then(successCallback(value){...},errorCallback(reason){...},notifyCallback(notify){...})中successCallback函数的参数。deferred.reject(reason)未成功解决其派生的promise。参数reason被用来说明未成功的原因。此时deferred实例的promise对象将会捕获一个任务未成功执行的错误,promise.catch(errorCallback(reason){...})。补充一点,promise.catch(errorCallback)实际上就是promise.then(null, errorCallback)的简写。异步校验注意事项
需要注意的是$asynValidators中校验函数的名称与validationMessage中错误码中的名称一致,这里都是IdAlreadyTaken。在页面输入完id之后会将value传入IdAlreadyTaken方法,调用后台的IdCheck服务,如果没有占用则在界面上显示对号,如果已占用则在页面显示叉号并提示“ID已经被注册”。
controller中的schema与data
1 | $scope.dataModel = {}; |
schema定义了数据结构,其中properties定义了元素,这里的元素与form中的元素(或form中元素的key)是对应的,包括id,name与note,事实上在最后生成的dataModel中包含的也是这三个属性。title是显示在界面上的输入框前的label,pattern是用正则表达式检验输入内容,可以规定输入域的长度,以及定义提示信息。required表示必须要填的元素,没有填就提交时会报错。在schema-form中,有些元素是有多种实现形式的,比如下拉框有三种实现形式,通过schema和form共同来实现。由于是新建team,dataModel在这里初始化为空,如果是更新团队等表单,则dataModel要用已有的团队信息进行初始化。
controller中表单的提交
1 | $scope.OK = function(form) { |
通过broadcast一个事件(schemaFormValidate)来强制执行校验,校验成功form.$valid为true时,执行新建团队的方法。
表单的模板
1 | <div class="panel panel-default"> |
这里双向绑定dataModel/schema/form,SchemaForm通过sf-options来设定全局属性,sf-options="{ formDefaults: { ngModelOptions: { updateOn: 'blur' } }}"此设置会使表单的每项都带上一个属性:ng-model-options=”form.ngModelOptions”,关于ng-model-options:常用于将“model与用户输入实时同步”改为“model在用户输入完(blur之后)再同步”。
参考网站
官网:
git地址:
https://github.com/json-schema-form/angular-schema-form
demo地址:
http://schemaform.io/examples/bootstrap-example.html