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. paip.互联网产品要成功的要素

    paip.互联网产品要成功的要素 作者Attilax  艾龙,  EMAIL:1466519819@qq.com  来源:attilax的专栏 地址:http://blog.csdn.net/atti ...

  2. 代码大全 MSIL语言程序设计

    .NET平台的编译器会将高级语言(C#,VB.NET,F#)编译成MSIL(微软中间语言)格式.熟悉MSIL语言,可以读懂一些加密程序混淆过的算法,这些算法几乎不能还原成高级语言,但是可以还原成MSI ...

  3. android: SQLite升级数据库

    如果你足够细心,一定会发现 MyDatabaseHelper 中还有一个空方法呢!没错,onUpgrade() 方法是用于对数据库进行升级的,它在整个数据库的管理工作当中起着非常重要的作用,可 千万不 ...

  4. Visual Studio 2013 and .NET 4.6

    I'm trying to set the 4.6 .NET framework for my project and in the settings, as it wasn't listed, I ...

  5. java文件同步性能测试

    2003同步速度

  6. j$(function() j$(document).ready 区别

    $j(document).ready(function(){}); // 或者  $j(function(){}); 第一个是直接使用Jquery调用function,第二个是在文档加载完毕后才去调用 ...

  7. fresco Bitmap too large to be uploaded into a texture

    fresco加载图片方法 布局文件引入 xmlns:fresco="http://schemas.android.com/apk/res-auto" <com.faceboo ...

  8. fastreport totalpage 只有设置doublepassreport为true 才正确否则为0

    fastreport totalpage 只有设置doublepassreport为true 才正确否则为0

  9. 搭建mongodb集群(副本集+分片)

    搭建mongodb集群(副本集+分片) 转载自:http://blog.csdn.net/bluejoe2000/article/details/41323051 完整的搭建mongodb集群(副本集 ...

  10. Hadoop源代码中的build-main.xml

    在Hadoop的每一个Project中,都有build-main.xml,如下图所示: 这个文件其实是通过maven-ant插件生成的,在hadoop的每一个Maven工程中,都有一个pom文件,在p ...