Angular Schema Form 扩展开发指南
概述
Angular Schema Form 是一个强大的表单生成工具,它能够根据 JSON Schema 自动生成表单。本文将深入探讨如何扩展 Angular Schema Form 的功能,包括创建自定义字段(add-on)和完全改变表单渲染方式(decorator)。
表单构建原理
核心构建流程
Angular Schema Form 使用 sfBuilder 服务递归地从"规范表单定义"(canonical form definition)构建 DOM 元素。规范表单定义是模式(schema)和表单定义合并后的内部表示形式,它是一个对象数组,每个对象至少包含 type
属性。
示例规范表单定义:
[
{
type: 'text',
key: 'name'
},
{
type: 'fieldset',
items: [
{
type: 'textarea',
key: 'comment'
}
]
}
]
实际构建过程
构建表单时,sfBuilder 服务会遍历规范表单定义,对于每种类型:
- 向装饰器请求模板
- 将模板添加到文档片段
- 检查该类型是否有构建器函数
- 如果有,则调用构建器函数处理模板
嵌套字段(如示例中的 fieldset)会通过构建器函数构建其子元素。
创建自定义字段(Add-on)
基本组成
一个自定义字段需要两个核心部分:
- 模板 - 定义字段的 HTML 结构
- 构建器函数 - 处理模板的逻辑
注册自定义字段
使用 schemaFormDecoratorsProvider.defineAddOn
方法注册自定义字段:
angular.module('myAddOnModule', ['schemaForm']).config(function(schemaFormDecoratorsProvider, sfBuilderProvider) {
schemaFormDecoratorsProvider.defineAddOn(
'bootstrapDecorator', // 目标装饰器名称
'awesome', // 表单类型
'templates/my/addon.html', // 模板路径
sfBuilderProvider.stdBuilders // 构建器函数列表
);
});
模板设计要点
一个良好的模板通常包含:
- 外层容器元素(用于添加 sfField 指令)
- sf-field-model 属性(用于模型绑定)
- schema-validate="form" 指令(启用模式验证)
- sf-message 指令(显示描述或错误信息)
示例模板:
<div>
<label>{{form.title}}</label>
<input sf-field-model schema-validate="form" type="text">
<div sf-message="form.description"></div>
</div>
模板编译注意事项
模板必须预先编译到 $templateCache
中,推荐使用构建工具(如 gulp-angular-templatecache)处理模板文件。
自定义构建器函数
构建器函数接收包含以下属性的 args 对象:
- fieldFrag: 文档片段(用于操作)
- form: 当前处理的表单定义
- lookup: 已添加项的引用列表
- state: 从父级传递的行为或默认值
- path: 表单定义的路径
- build: 用于从表单定义构建子元素的函数
示例构建器:
function textareaBuilder(args) {
var textareaFrag = args.fieldFrag.querySelector('textarea');
var maxLength = args.form.maxlength || false;
if (textareaFrag && maxLength) {
textareaFrag.setAttribute('md-maxlength', maxLength);
}
}
创建装饰器(Decorator)
装饰器本质上是多个自定义字段的集合,至少需要覆盖模式可以默认的基本字段类型。
注册装饰器示例:
angular.module('myDecoratorModule', ['schemaForm']).config(function(schemaFormDecoratorsProvider, sfBuilderProvider) {
schemaFormDecoratorsProvider.defineDecorator('awesomeDecorator', {
textarea: {template: base + 'textarea.html', builder: sfBuilderProvider.stdBuilders},
button: {template: base + 'submit.html', builder: sfBuilderProvider.stdBuilders},
text: {template: base + 'text.html', builder: sfBuilderProvider.stdBuilders},
'default': {template: base + 'default.html', builder: sfBuilderProvider.stdBuilders}
}, []);
});
设置模式默认值
可以通过修改 schemaFormProvider.defaults
对象来定义特定模式类型的默认字段类型。
示例:为日期格式字符串设置默认日期选择器:
var datepicker = function(name, schema, options) {
if (schema.type === 'string' && (schema.format === 'date' || schema.format === 'date-time')) {
var f = schemaFormProvider.stdFormObj(name, schema, options);
f.key = options.path;
f.type = 'datepicker';
options.lookup[sfPathProvider.stringify(options.path)] = f;
return f;
}
};
schemaFormProvider.defaults.string.unshift(datepicker);
核心构建器详解
sfField 构建器
功能:向模板的第一个子元素添加 sf-field
指令,该指令将表单定义对象导出为作用域中的 form
变量。
condition 构建器
功能:检查表单定义中的 condition
选项,如果存在则为所有顶级元素添加 ng-if
指令。
ngModel 构建器
功能:确保模型值的正确绑定,处理 sf-field-model
属性的三种形式:
sf-field-model
:添加ng-model
指令sf-field-model="attribute name"
:设置指定属性的值为模型路径sf-field-model="replaceAll"
:替换元素所有属性中的$$value$$
为模型路径
ngModelOptions 构建器
功能:如果表单定义中有 ngModelOptions
选项,则向第一个子元素添加 ng-model-options
属性。
simpleTransclusion 构建器
功能:递归构建表单项,适用于 fieldset 等容器类型字段。
实用指令
sf-field 指令
该指令为模板添加作用域,提供以下实用功能:
| 名称/方法 | 功能描述 | |----------|----------| | form | 当前字段的表单定义对象 | | showTitle() | 检查是否显示标题的快捷方法 | | ngModel | ngModel 控制器 | | evalInScope(expr, locals) | 在当前作用域中求值表达式 | | evalExpr(expr, locals) | 在主 sf-schema 指令的父作用域中求值表达式 | | interp(expr, locals) | 插值可能包含 {{ }}
序列的表达式 | | buttonClick($event, form) | 执行表单的 onClick 处理程序 | | hasSuccess() | 检查是否显示成功状态的快捷方法 | | hasError() | 检查是否显示错误状态的快捷方法 |
注意:errorMessage
方法已弃用,推荐使用 sf-message
指令替代。
通过本文的指南,开发者可以充分利用 Angular Schema Form 的扩展能力,创建符合特定需求的自定义表单组件和渲染方式。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考