Angular Schema Form使用方法

完成功能

这是一种支持多种元素的表单,包括下拉框,编辑器,日期选择器,颜色选择器等。
Angular Schema Form是分schema,form,data三块Json去定义表单。在controller里面,schema定义了数据结构,form定义了UI,model绑定了用户的输入。在html中使用统一的写法,使用ng-schema,ng-form与ng-model指令分别绑定,最后可呈现出不同的表单。

环境配置

  1. 先通过npm下载项目,使用指令npm install angular-schema-form,找到项目中的dist文件夹,拿到压缩文件bootstrap-decorator.min.jsschema-form.min.js
  2. 把压缩文件bootstrap-decorator.min.jsschema-form.min.js放入项目alogic-itportal-web的lib文件夹下。压缩文件放在lib文件夹下将在发布时保持原有格式,不会被压缩。
  3. 参考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。
  4. 在使用到表单的入口,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
2
3
4
5
6
7
8
9
jscross.widget('newTeam', {
templateUrl: relativePath.plugin + 'manage/template/team/new.team.tpl.html',
replace: false,
restrict: 'A',
controller: 'newTeamCtrl',
scope: {
current: '='
}
});

分别绑定了模板和控制器,没有太多需要解释。

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的一种内置服务,它可以使你异步地执行函数,并可以获取到函数的返回值。

  1. deferred.resolve(value) 成功解决(resolve)了其派生的promise。参数value将来会被用作promise.then(successCallback(value){...}, errorCallback(reason){...},notifyCallback(notify){...})中successCallback函数的参数。
  2. 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
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
$scope.dataModel = {};
$scope.schema = {
'type': 'object',
'title': 'new-team',
'properties': {
'id': {
'title': 'ID',
'type': 'string',
'pattern': '^[a-zA-Z0-9._-]{3,}$'
},
'name': {
'title': '名称',
'type': 'string'
},
'note': {
'title': '简介',
'type': 'string',
'maxLength': '70',
'validationMessage': '太长啦,装不下啦'
}

},
'required': [
'id',
'name'
]
};

schema定义了数据结构,其中properties定义了元素,这里的元素与form中的元素(或form中元素的key)是对应的,包括id,name与note,事实上在最后生成的dataModel中包含的也是这三个属性。title是显示在界面上的输入框前的label,pattern是用正则表达式检验输入内容,可以规定输入域的长度,以及定义提示信息。required表示必须要填的元素,没有填就提交时会报错。在schema-form中,有些元素是有多种实现形式的,比如下拉框有三种实现形式,通过schema和form共同来实现。由于是新建team,dataModel在这里初始化为空,如果是更新团队等表单,则dataModel要用已有的团队信息进行初始化。

controller中表单的提交

1
2
3
4
5
6
7
8
$scope.OK = function(form) {
// First we broadcast an event so all fields validate themselves
$scope.$broadcast('schemaFormValidate');
// Then we check if the form is valid
if(form.$valid) {
newTeam();
}
};

通过broadcast一个事件(schemaFormValidate)来强制执行校验,校验成功form.$valid为true时,执行新建团队的方法。

表单的模板

1
2
3
4
5
6
7
8
9
10
11
12
13
<div class="panel panel-default">
<div class="panel-body">
<div class="col-md-8">
<div>
<form name="newTeamForm" sf-model="dataModel" sf-schema="schema" sf-form="form" sf-options="{ formDefaults: { ngModelOptions: { updateOn: 'blur' } }}"></form>
</div>
</div>
<div class="col-md-8" style="text-align:center;">
<button class="btn btn-default btn-success margin-right-20" type="submit" ng-click="OK(newTeamForm)">完成</button>
<button class="btn btn-default" type="submit" ng-click="cancel()">取消</button>
</div>
</div>
</div>

这里双向绑定dataModel/schema/form,SchemaForm通过sf-options来设定全局属性,sf-options="{ formDefaults: { ngModelOptions: { updateOn: 'blur' } }}"此设置会使表单的每项都带上一个属性:ng-model-options=”form.ngModelOptions”,关于ng-model-options:常用于将“model与用户输入实时同步”改为“model在用户输入完(blur之后)再同步”。

参考网站

官网:

http://schemaform.io/

git地址:

https://github.com/json-schema-form/angular-schema-form

demo地址:

http://schemaform.io/examples/bootstrap-example.html

资料参考地址:

http://www.cnblogs.com/natsu12/p/5417092.html

为本少女加个鸡腿吧!
显示 Gitment 评论