目录
- 概述
- OOD框架核心概念
- 组件架构设计
- 组件类定义规范
- 组件生命周期管理
- 数据绑定与状态管理
- 事件处理机制
- 样式与外观管理
- API集成与数据交互
- 动作关联机制
- 设计器兼容性
- 最佳实践
- 常见问题与解决方案
概述
OOD(Object-Oriented Development)框架是一个面向对象的前端开发框架,旨在提供高度可复用、可维护和可扩展的组件化开发解决方案。本手册将详细介绍如何开发符合OOD规范的高级组件。
什么是高级组件?
高级组件是指:
- 功能完整:具备完整的业务功能和交互逻辑
- 可复用性强:能够在不同场景下重复使用
- 封装性好:对外暴露清晰的接口,隐藏内部实现细节
- 扩展性佳:支持通过配置和扩展机制满足不同需求
- 设计器兼容:能够与可视化设计器无缝集成
OOD框架核心概念
1. 类系统(Class System)
OOD框架基于类的继承体系,所有组件都是通过ood.Class定义的类实例。
ood.Class("ModuleName", 'BaseClass', {
Instance: {
// 实例方法和属性
},
Static: {
// 静态方法和属性
}
});
2. 模块系统(Module System)
OOD框架支持模块化开发,通过命名空间组织代码:
// 定义命名空间
ood.Mobile.OA.ComponentName
3. 组件层次结构
ood.Module
├── ood.UI
│ ├── ood.absValue (值组件)
│ └── ood.absList (列表组件)
└── ood.absObj (基础对象)
高级组件架构设计
设计原则
- 单一职责原则:每个组件只负责一个特定的功能领域
- 开闭原则:对扩展开放,对修改关闭
- 里氏替换原则:子类能够替换父类而不影响程序正确性
- 接口隔离原则:客户端不应该依赖它不需要的接口
- 依赖倒置原则:高层模块不应该依赖低层模块
组件架构图
graph TD
A[高级组件] --> B[Instance部分]
A --> C[Static部分]
B --> D[生命周期方法]
B --> E[依赖管理]
B --> F[事件处理]
B --> G[功能方法]
B --> H[初始化逻辑]
C --> I[模板定义]
C --> J[样式定义]
组件类定义规范
标准类结构
/**
* 组件描述
*/
ood.Class("ood.Namespace.ComponentName", 'BaseClass', {
Instance: {
// 必须包含的初始化方法
initialize: function() {
this.constructor.upper.prototype.initialize.apply(this, arguments);
// 组件特定初始化逻辑
},
// 依赖声明
Dependencies: [],
// 必需模块声明
Required: [],
// 事件处理器
events: {},
// 用户扩展方法
functions: {},
// 组件初始化方法
iniComponents: function() {
var host = this, children = [], properties = {},
append = function(child) {
children.push(child.get(0));
};
ood.merge(properties, this.properties);
// 组件创建逻辑
return children;
}
},
Static: {
// 模板定义
Templates: {},
// 样式定义
Appearances: {}
}
});
实例方法详解
initialize方法
initialize: function() {
// 调用父类初始化方法(必须)
this.constructor.upper.prototype.initialize.apply(this, arguments);
// 组件私有属性初始化
this._privateProperty = null;
this._state = {};
}
Dependencies和Required
// 声明依赖的模块
Dependencies: [
'ood.UI.Button',
'ood.UI.Input'
],
// 声明必需的模块
Required: [
'ood.DataBinder'
]
组件生命周期管理
生命周期阶段
- 创建阶段:组件类定义和实例化
- 初始化阶段:调用initialize和iniComponents方法
- 渲染阶段:组件被添加到DOM中
- 运行阶段:组件正常运行,处理用户交互
- 销毁阶段:组件被移除和清理
生命周期方法
Instance: {
initialize: function() {
// 初始化阶段
},
iniComponents: function() {
// 组件初始化阶段
},
// 可选的生命周期方法
beforeRender: function() {
// 渲染前调用
},
afterRender: function() {
// 渲染后调用
},
destroy: function() {
// 销毁阶段
}
}
数据绑定与状态管理
数据源驱动设计
高级组件应以数据源驱动为主:
// 通过dataSource属性配置数据来源
component.setDataSource(dataBinder);
// 通过dataField映射字段
component.setDataField('fieldName');
// 调用bindDataSource方法完成数据绑定
component.bindDataSource();
内部状态管理
Instance: {
initialize: function() {
this.constructor.upper.prototype.initialize.apply(this, arguments);
// 维护必要的临时状态
this._selectedItem = null;
this._dataCache = {};
},
functions: {
// 获取选中项
getSelectedItem: function() {
return this._selectedItem;
},
// 设置选中项
setSelectedItem: function(item) {
this._selectedItem = item;
// 状态变更应优先通过数据源更新触发UI响应
this.updateUI();
}
}
}
事件处理机制
事件命名规范
events: {
// 值改变事件
onChanged: function(profile, oldValue, newValue) {},
// 选中事件
onChecked: function(profile, checked) {},
// 值设置事件
onValueSet: function(profile, value) {},
// 列表项选中事件
onItemSelected: function(profile, index, item) {},
// 列表项添加事件
onItemAdded: function(profile, item) {},
// 列表项删除事件
onItemRemoved: function(profile, index, item) {},
// 数据加载完成事件
onDataLoad: function(profile, data) {},
// 数据加载错误事件
onDataError: function(profile, error) {}
}
事件作用域管理
// 事件处理器必须定义在具体组件内部
events: {
onItemClick: function(profile, index, item) {
// 保持事件逻辑与组件的封装性
// 处理时应使用对应的组件对象进行响应
}
}
样式与外观管理
样式定制规范
// 使用setCustomStyle方法进行样式定制
component.setCustomStyle({
"KEY": {
"background-color": "#fff",
"border": "1px solid #ccc"
},
"CONTAINER": {
"padding": "10px"
}
});
// 组件顶级DOM使用'KEY'关键字作为key
// 虚拟DOM名称作为其他key
样式变量使用
:root {
--mobile-primary: #007AFF;
--mobile-success: #4CD964;
--mobile-warning: #FF9500;
--mobile-danger: #FF3B30;
--mobile-bg-primary: #FFFFFF;
--mobile-bg-secondary: #F2F2F7;
--mobile-text-primary: #000000;
--mobile-text-secondary: #8E8E93;
--mobile-border-color: #C6C6C8;
}
API集成与数据交互
APICaller集成
iniComponents: function() {
var host = this, children = [], properties = {},
append = function(child) {
children.push(child.get(0));
};
ood.merge(properties, this.properties);
// 创建APICaller实例
var apiCaller = ood.create("ood.APICaller");
apiCaller.setHost(host, "apiCaller");
apiCaller.setName("apiCaller");
// 配置API调用参数
apiCaller.setQueryURL("/api/data");
apiCaller.setQueryMethod("GET");
apiCaller.setProxyType("AJAX");
apiCaller.setRequestType("JSON");
apiCaller.setResponseType("JSON");
// 设置成功回调
apiCaller.onData([
{
"desc": "数据加载成功",
"type": "function",
"target": "setData",
"args": ["{temp$.okData}"]
}
]);
// 设置错误回调
apiCaller.onError([
{
"desc": "数据加载失败",
"type": "event",
"target": "onDataError",
"args": ["{temp$.koData}"]
}
]);
append(apiCaller);
return children;
}
参数映射机制
上行参数(requestDataSource)
// 用于收集组件数据并发送至服务端
apiCaller.setRequestDataSource([
{
"name": "form1",
"type": "FORM",
"path": "formData"
}
]);
下行参数(responseDataTarget)
// 用于将服务端响应数据填充到指定组件
apiCaller.setResponseDataTarget([
{
"name": "list1",
"type": "LIST",
"path": "data.list"
}
]);
动作关联机制
动作定义
// 通过actions配置对象定义事件对应的执行动作
var component = new (ood.Class.getInstance('ComponentName'))({
actions: {
onLoad: {
actions: [
{
"desc": "执行关联动作",
"type": "function",
"target": "someFunction",
"args": ["{data}"]
}
]
}
}
});
动作执行
functions: {
executeAction: function(actionName, params) {
// 提供executeAction方法实现动作触发
var actions = this.actions[actionName];
if (actions && actions.actions) {
ood.pseudocode._callFunctions(actions, params, this, null, null, actionName);
}
}
}
设计器兼容性
设计器支持
// 支持在可视化设计器中配置和使用
iniComponents: function() {
// 使用命令方式组合视图并设置组件属性
var container = ood.create("ood.UI.Div");
container.setHost(host, "container");
container.setLeft(0);
container.setTop(0);
container.setWidth("100%");
container.setHeight("100%");
// 使用 KEY:VALUE 方式组合样式
container.setCustomStyle({
"KEY": {
"padding": "var(--mobile-spacing-md)"
}
});
return [container.get(0)];
}
属性暴露
// 确保组件属性可以通过设计器配置
Instance: {
properties: {
// 组件基础属性
width: '100%',
height: 'auto',
caption: '组件标题'
}
}
最佳实践
1. 组件设计最佳实践
// 优先使用已有的业务组件
var list = ood.create("ood.UI.List"); // 而不是ood.UI.Div
// 根据数据属性判断是集合还是单个数据项
if (Array.isArray(data)) {
// 使用列表组件
} else {
// 使用值组件
}
// 根据展示需求进一步查看相关子类再做选择判断
2. 数据管理最佳实践
// 使用APICaller进行数据交互
var apiCaller = ood.create("ood.APICaller");
// 通过输入输出映射完成反向绑定
apiCaller.setRequestDataSource([...]);
apiCaller.setResponseDataTarget([...]);
// 维护数据流的清晰性
// 确保UI状态与服务调用结果保持一致
3. 事件处理最佳实践
// 使用组件原生支持的事件
component.onItemSelected(function(profile, index, item) {
// 处理选中事件
});
// 遵循事件作用域管理规范
// 保持事件处理逻辑的封装性
// 动作事件方面尽可能使用已有方法
4. 样式设计最佳实践
// 使用KEY:VALUE方式组合样式
component.setCustomStyle({
"KEY": {
"background-color": "var(--mobile-bg-primary)"
}
});
// 避免抽象为独立CSS类
// 确保样式信息可被设计器读取
// 使用CSS变量确保样式一致性
5. 性能优化最佳实践
// 避免不必要的DOM操作
// 合理使用事件委托
// 优化组件渲染性能
// 减少内存泄漏风险
常见问题与解决方案
1. 组件初始化问题
问题:组件初始化时出现错误 解决方案:
initialize: function() {
try {
this.constructor.upper.prototype.initialize.apply(this, arguments);
// 组件特定初始化逻辑
} catch (e) {
console.error('组件初始化失败:', e);
}
}
2. 事件处理问题
问题:事件处理器未被正确调用 解决方案:
// 确保事件处理器定义在组件内部
events: {
onCustomEvent: function(profile, data) {
// 事件处理逻辑
}
}
// 确保正确触发事件
this.fireEvent('onCustomEvent', data);
3. 数据绑定问题
问题:数据绑定不生效 解决方案:
// 确保正确配置数据源
component.setDataSource(dataBinder);
component.setDataField('fieldName');
// 确保调用绑定方法
component.bindDataSource();
4. 样式问题
问题:组件样式未正确应用 解决方案:
// 使用setCustomStyle方法
component.setCustomStyle({
"KEY": {
"background-color": "#fff"
}
});
// 确保CSS变量已定义
5. API调用问题
问题:APICaller调用失败 解决方案:
// 检查API配置
apiCaller.setQueryURL("/api/data");
apiCaller.setQueryMethod("GET");
// 检查回调设置
apiCaller.onData([...]);
apiCaller.onError([...]);
// 确保正确调用
apiCaller.invoke();
附录
附录A:常用组件类继承关系
ood.Module
├── ood.UI
│ ├── ood.absValue
│ └── ood.absList
附录B:标准方法命名规范
- getXXX:获取属性值
- setXXX:设置属性值
- onXXX:事件处理器
- initXXX:初始化方法
- bindXXX:绑定方法
- loadXXX:加载方法
- saveXXX:保存方法
附录C:常用事件处理器
- onChanged:值改变事件
- onChecked:选中事件
- onValueSet:值设置事件
- onItemSelected:列表项选中事件
- onItemAdded:列表项添加事件
- onItemRemoved:列表项删除事件
- onDataLoad:数据加载完成事件
- onDataError:数据加载错误事件
附录D:APICaller参数类型
请求类型(requestType)
- FORM:表单格式请求数据
- JSON:JSON格式请求数据
- XML:XML格式请求数据
- SOAP:SOAP协议请求数据
响应类型(responseType)
- JSON:JSON格式响应数据
- TEXT:文本格式响应数据
- XML:XML格式响应数据
- SOAP:SOAP协议响应数据
代理类型(proxyType)
- AJAX:标准AJAX请求
- JSONP:跨域JSONP请求
- XDMI:跨域消息接口请求
数据源类型(requestDataSource.type)
- FORM:表单数据
- DATABINDER:数据绑定器
- TREEVIEW:树形视图
- GALLERY:画廊组件
- TREEGRID:树形表格
- PAGEBAR:分页组件
目标类型(responseDataTarget.type)
- TREEGRID:树形表格
- LIST:列表组件
- FORM:表单组件
- DATABINDER:数据绑定器