dataServices


数据服务的管理器;首先看下具体的代码

//数据服务
dataServices = st.factory({
name: "dataServices",
proto: {
//通过操作方法;type:操作类型; op:操作参数
operate: function(type, op) {…………},
//查询方法;op:操作参数
search: function(op) {…………},
//更新方法;op:操作参数
update: function(op) {……}
},
base: {
//查询接口
search: function(op) {},
//更新接口
update: function(op) {},
//通用初始化参数接口
initOptions : function(op){}
}
})

使用factory创建,加入了三个方法operate,search,update。使用的时候,直接通过这三个方法来操作具体注册的数据服务(在op中设定dsType)。

同时base定义了三个数据服务的三个基类接口,search,update,initOptions;

op:既设置的参数(options,在smartjs中统一做op的简写),只有六个固定参数。其他都是都是由具体的数据服务定义;

    op = {
//数据服务类型
dsType : str,
//过滤参数
param :obj,
//过滤器
fitler : fn | obj
//更新的数据
data :obj,
//成功以后执行的方法
success : success,
//失败以后执行的方法
error : error
};

其中,param与filter可以根据不同的数据服务类型来区别使用,比如只是客户端的可以使用filter,服务端的可以使用params;

注意:虽然op中有了success,error,但添加dataService的时候,尽量使用promise的处理。

代码示例

通过dataServices的add(factory内置)的方法来注册数据服务;实现了search和update两个接口。另外一个initOptions是需要对op初始化的是重写

首先注册一个模拟后台异步数据服务 - server;只接受params来过滤数据:

var dataServices = st.dataServices,
dataManager = st.dataManager,
_db = [],
_cache = []; //将params解析成过滤方法
function buildFilterByParams(params) {
if (params) {
return function(item) {
var check = true;
$.each(params, function(name, value) {
if (item[name] !== value) {
check = false;
return check;
}
})
return check;
}
}
} //取对象数据,测试使用array只取第一条
function getData(data) {
return $.isArray(data) ? data[0] : data;
} function buildFitler(filter) {
if (filter && typeof filter === 'object') {
return buildFilterByParams(filter);
}
return filter;
} //模拟服务端异步返回数据,只接受params
dataServices.add("server", {
search: function(op) {
//模拟异步查询
setTimeout(function() {
var result,
filter = op.filter; result = filter ? _db.filter(filter) : _db; op.success && op.success(result);
}, 100);
},
update: function(op) {
//模拟异步更新
setTimeout(function() {
var filter = op.filter,
data = getData(op.data); if (filter) {
//测试使用,只更新第一条匹配数据
$.each(_db, function(i, item) {
if (filter(item)) {
_db[i] = data;
return false;
}
})
} else {
_db = op.data || [];
} op.success && op.success(op.data); }, 100);
},
initOptions: function(op) {
//初始化设置参数将params编译成filter过滤方法
op.filter = buildFilterByParams(op.params);
}
});

然后在注册一个模拟客户端取数据的缓存服务服务 - cache,使用filter进行过滤。

//模拟客户端本地存储
dataServices.add("cache", {
search: function(op) {
var result, filter = op.filter; result = filter ? _cache.filter(filter) : _cache; op.success && op.success(result);
},
update: function(op) {
var filter = op.filter,
data = getData(op.data); if (filter) {
//测试使用,只更新第一条匹配数据
$.each(_cache, function(i, item) {
if (filter(item)) {
_cache[i] = data;
return false;
}
})
} else {
_cache = op.data || [];
}
op.success && op.success(op.data);
},
initOptions: function(op) {
//生成fitler,当filter为obj类型时,编译成fn
op.filter = buildFitler(op.filter);
}
});

看一下server的测试用例,直接使用dataServices对象进行操作,使用dsType来设置具体的数据类型;

describe('dataServices Test', function() {
it("update", function(endTest) {
//更新server的数据
dataServices.update({
dsType: 'server',
data: [{
name: 'user1',
age: 20
}, {
name: 'user2',
age: 30
}],
success: function(result) {
expect(_db.length).toBe(2);
endTest();
}
});
}) it("search", function(endTest) {
//重新server的数据
dataServices.search({
dsType: 'server',
params: {
name: 'user1'
},
success: function(result) {
expect(result.length).toBe(1);
expect(result[0].age).toBe(20);
endTest()
}
}); })
});

dataManager


数据管理器,同样使用factory构建,但是选用的类型为'class',需动态初始化;扩展创建dm的方法-ceate和生成filter的方法-buildFilter;

另外在基类中,klassInit,get,set,onHandler,addHandler,fireHandler为实现方法;其他的都是接口,需要根据具体的数据管理进行实现;

//数据管理器
dataManager = st.factory({
name: "dataManager",
type: "class",
proto: {
//创建dm方法
create: function(type, op) {},
//生成fitler方法
buildFilter: function(filter,conf) {}
},
base: {
klassInit: function(op) {},
//dm初始化方法
init: function(op) {},
//获取数据
get: function(conf) {},
//设置数据
set: function(conf) {},
//注册方法到事件委托,handler委托名称:get,set,trigger
onHandler: function(handler, fnName, fn, priority, mode) {},
//添加事件委托
addHandler: function() {},
//执行事件委托
fireHandler: function(name, args) {},
//dm内置查询
innerSearch: function(op) {},
//dm内置更新
innerUpdate: function(op) {},
//检查数据是否为空
checkEmpty: function(data, conf) {},
//验证方法
validate: function() {},
//清空方法
clear: function() {},
//初始化数据服务配置方法
setDataSerive : function(config){}
}
});

添加datamanger示例

添加一个简单的table类型的数据管理,(注只做测试演示,与真正的datamanger-table不是同一个)

//添加一个简单的table类型的数据管理
dataManager.add("Table", {
init: function() {
this._data = [];
},
//dm内置查询
innerSearch: function(conf) {
var filter = conf ? buildFitler(conf.filter) : null;
return filter ? this._data.filter(filter) : this._data;
},
//dm内置更新
innerUpdate: function(conf) {
var isUpdate, _data = this._data,
data = conf.data,
updateData, filter; conf && (filter = buildFitler(conf.filter)); if (filter) {
updateData = getData(data);
//筛选数据
_data.forEach(function(item, i) {
if (filter(item)) {
_data[i] = updateData;
isUpdate = true;
return false;
}
})
isUpdate || _data.push(updateData);
} else {
this._data = data || [];
}
return data;
},
//判断数据是否为空
checkEmpty: function(data, conf) {
return data === undefined || data.length === 0;
},
//清空数据
clear: function() {
this._data = [];
}
});

在来看一下怎么使用这个dm,下面列子中使用了内置的查询和更新;

//创建一个tabel的manager
var dm1 = dataManager.create("Table"); it("update", function() {
dm1.innerUpdate({
data: [{
name: 'user1',
age: 10
}]
});
expect(dm1._data.length).toBe(1);
expect(dm1._data[0].name).toBe('user1');
}) it("search", function() {
var result = dm1.innerSearch();
expect(result.length).toBe(1);
expect(result[0].name).toBe('user1');
}) it("update by filter", function() {
//找不到匹配的数据,则插入新数据
dm1.innerUpdate({
data: {
name: 'user3',
age: 10
},
//方法过滤器
filter: function(user) {
return user.name == 'user3';
}
});
expect(dm1._data.length).toBe(2);
expect(dm1._data[1].name).toBe('user3'); //更新数据
dm1.innerUpdate({
data: {
name: 'user3',
age: 40
},
//方法过滤器
filter: function(user) {
return user.name == 'user3';
}
}); expect(dm1._data.length).toBe(2);
expect(dm1._data[1].age).toBe(40);
}) it("search by filter", function() {
var result = dm1.innerSearch({
//方法过滤器
filter: function(user) {
return user.name == 'user3';
}
});
expect(result.length).toBe(1);
expect(result[0].age).toBe(40);
}) it("search by params", function() {
var result = dm1.innerSearch({
//参数过滤器
filter: {
name: 'user3'
}
});
expect(result.length).toBe(1);
expect(result[0].age).toBe(40);
})

在结合dataService来看个查询的例子,在这里使用get操作,而不是innerSearch;get和set这两个动作都会进入数据管理流程,策略才会生效。而innerSearch和innerUpdate则是只查询dm内部。

在这个例子中,get动作会首先在dm内部查询,找不到数据,在会进入ds查询,然后将ds查询的数据同步到dm中。(详细的流程见dataManager介绍

it("get from ds and update", function(endTest) {
dm1.clear();
//首先会在dm内部查询,找不到数据然后在到server上查询
dm1.get({
//设置数据服务为server
dataServices: {
dsType: 'server'
},
success: function(result) {
expect(result).toBeDefined();
expect(result[0].name).toBe('user1');
expect(dm1._data[0].name).toBe('user1');
endTest();
}
})
}) it("get from ds and no update", function(endTest) {
dm1.clear();
dm1.get({
//设置查询不更新
update: false,
dataServices: {
dsType: 'server'
},
success: function(result) {
expect(dm1._data.length).toBe(0);
endTest();
}
})
})

在看一个set的例子:

it("set to ds", function(endTest) {
//更新到ds
dm1.set({
data: [{
name: "userUpdate"
}],
dataServices: {
dsType: 'server'
},
success: function(result) {
expect(_db.length).toBe(1);
expect(_db[0].name).toBe('userUpdate');
endTest();
}
}) }) it("set to ds by params", function(endTest) {
//根据条件更新到ds,条件同时在dm和ds中生效
dm1.set({
data: [{
name: "userUpdate"
}],
params: {
id: 1
},
dataServices: {
dsType: 'server'
},
success: function(result) {
expect(_db.length).toBe(2);
expect(_db[0].name).toBe('userUpdate');
endTest();
}
})
})

下篇详细介绍策略参数的api和场景分析

更多的例子见请到smartjs的github上查看

smartjs - DataManager API的更多相关文章

  1. smartjs - DataManager 场景示例分析 - 数据懒加载

    发一张policy的参数图设置图: 场景1 - 数据的懒加载/延迟加载 在很多时候,为了提高网页的加载速度,减少不必要的开销,会将页面的数据拆分成几个部分,首先加载呈现可视区域内的数据,然后剩下来的会 ...

  2. smartjs 0.3 DataManager 发布&介绍

    在0.3版加入了DataManager,基于策略的数据管理模块:是SmartJS中比较重要的一个系列.整个个DataManager模块包括有:dataManager,dataPolicyManager ...

  3. smartJS 0.1 API 讲解 - PromiseEvent

    上篇简单的介绍smartjs了一些通用方法的api.这篇介绍基础的PromiseEvent(这个名字一直没想好,以前准备用callbacks的,但避免与jquery混淆,st的命名空间可以直接挂到$上 ...

  4. smartJS 0.1 API 讲解 - FlowController

    本篇介绍0.1版中最后一个特性,FlowController:同时也对第一版总结一下,因为近两年全部都是在搞前端,都是做一些js框架类的东西,也做了不少有意思的功能,做smartjs对我来说一个是对自 ...

  5. smartJS 0.1 API 讲解 - Trigger

    上篇介绍了PromiseEvent,本篇介绍Trigger - 基于Promise的aop的体现:(感觉自己的对这些命名一直都很挫,也懒得想了,所以就凑合的用) Trigger 在目标对象上加入触发器 ...

  6. 百度地图API使用记录

    用户数据图层的总教程: 就是把用户数据存到LBS云里面,应用从云里面读数据 http://developer.baidu.com/map/jsdevelop-9.htm 上传数据的地方: http:/ ...

  7. SmartJS 系列规划分享和背景介绍

    发布了smartjs后,有朋友问:“没看懂究竟是干嘛的”.唉,打击了,每次我都想高唱其实你不懂我的心. 今天把相关的东西都整理了一遍,给大家介绍一下.里面绝大多数都已经实现过,有些则是有新的思路重做或 ...

  8. SmartJS 第一期(0.1)发布 - AOP三剑客

    隔了好久才终于又发布了一点东西,SmartJS是最近才开始搞的一个开源js库,目的是做一些比较有特点的事情(smartjs暂时也是依赖于jquery). SmartJS的内容规划比较多,也无法在短时间 ...

  9. 【高德地图API】从零开始学高德JS API(四)搜索服务——POI搜索|自动完成|输入提示|行政区域|交叉路口|自有数据检索

    原文:[高德地图API]从零开始学高德JS API(四)搜索服务——POI搜索|自动完成|输入提示|行政区域|交叉路口|自有数据检索 摘要:地图服务,大家能想到哪些?POI搜素,输入提示,地址解析,公 ...

随机推荐

  1. Linux中ctrl-c, ctrl-z, ctrl-d 区别

    在Linux中: ctrl-c: ( kill foreground process )   发送 SIGINT 信号给前台进程组中的所有进程,强制终止程序的执行: ctrl-z: ( suspend ...

  2. 详解Bootstrap按钮组件(二)

    按钮下拉菜单 按钮下拉菜单仅从外观上看和下拉菜单效果基本上是一样的.它们唯一的不同是外部容器div.dropdown换成了div.btn-group <div class="btn-g ...

  3. 更改Windows系统的密码之后,SQL Server 2008服务无法启动

    问题:更改Windows操作系统的密码之后,SQL Server 2008服务无法启动. 原因:SQL Server服务需要使用操作系统的某个登录账户. 解决:需要在服务的属性窗口中修改账户密码,然后 ...

  4. 解决安卓SDK更新连不通问题

    http://wenku.baidu.com/link?url=d7t81OFF4_o2YF9iBne-azyovROGPGOozMgWKNyAIQK8vtI0mIjvzpfdOXg7KOobu202 ...

  5. ubuntu下安装 infer

    sudo apt-get updatesudo apt-get upgradesudo apt-get install git openjdk-7-jdk m4 zlib1g-dev python-s ...

  6. GO語言視頻教程下載

    需要的朋友可以加QQ群195112,在群共享內可以下載到.

  7. Javascript 严格模式

    简介 严格模式是一种将更好的错误检查引入代码中的方法. 在使用严格模式时,你无法使用隐式声明的变量.将值赋给只读属性或将属性添加到不可扩展的对象等. 声明严格模式 可以通过在文件.程序或函数的开头添加 ...

  8. PPTP VPN 一键安装包(图文,OpenVZ适用)[zz]

    [介绍] VPN的英文全称是“Virtual Private Network”,中文名叫“虚拟专用网络”.VPN可以通过特殊加密的通讯协议连接到Internet上,在位于不同地方的两个或多个内部网之间 ...

  9. MYSQL INSERT INTO SELECT 不插入重复数据

    INSERT INTO `b_common_member_count` (uid) SELECT uid FROM `b_common_member` WHERE uid NOT IN (SELECT ...

  10. [转] jQuery对象与DOM对象之间的转换

    http://wozailongyou.iteye.com/blog/299311 http://blog.allenm.me/2009/07/jquery%E4%B8%ADid%E5%92%8Cdo ...