Lizard 分享
Lizard
中的cModel
&cStore
演讲者: 王兵兵
Lizard
中的cModel
&cStore
演讲者: 王兵兵
cModel
类中封装了一系列的ajax
请求的常用方法.
主要用于继承,不会单独使用.
/**
* {Boolean} 可覆盖,提交参数是否加入head
*/
this.usehead = true;
//head数据
this.head = CommonStore.HeadStore.getInstance();
/**
* {Store} 可选,
*/
this.result = null;
// @description 替代headstore信息的headinfo
this.headinfo = null;
// @param {Boolean} 可选,只通过ajax获取数据,不做localstorage数据缓存
this.ajaxOnly = false;
//@param {Boolean} 可选,是否是用户相关数据
this.isUserData = false;
// request中的数据
this.param = {};
// 协议
this.protocol = "http";
setHead: function(head) {
if (!head instanceof AbstractStore) {
throw 'Set head is not a store';
}
this.head = head;
},
getHead: function() {
return this.head;
},
/**
* 获得参数存储器
*/
getParamStore: function() {
return this.param;
},
/**
* 设置参数存取器
*/
setParamStore: function(param) {
if (typeof param !== 'object') throw 'Set param is not a store';
this.param = param;
},
/**
* 获得结果存储器
*/
getResultStore: function() {
return this.result;
},
// 设置结果存取器
setResultStore: function(result) {
if (typeof result !== 'object') throw 'Set result is not a store';
this.result = result;
},
/**
* 清空结果数据
*/
clearResult: function() {
if (this.result && typeof this.result.remove === 'function') {
this.result.remove();
}
},
/**
* 重写父类
* 设置提交参数
* @param {String} param 提交参数
* @return void
*/
setParam: function(key, val) {
var param = {};
if (typeof key === 'object' && !val) {
param = key;
} else {
param[key] = val;
}
for (var i in param) {
if (this.param instanceof AbstractStore) {
this.param.setAttr(i, param[i]);
} else {
cObject.set(this.param, i, param[i]);
}
}
},
//重写父类
getParam: function() {
return this.param instanceof AbstractStore ? this.param.get() : this.param;
},
buildurl: function() {
if (cUtility.validate.isUrl(this.url)) {
return this.url.replace(this.urlParseRet.hostname, this.baseurl.domain);
} else {
return this.protocol + '://' + this.baseurl.domain + '/' + this.baseurl.path + (typeof this.url === 'function' ? this.url() : this.url);
}
},
excute: function(onComplete, onError, ajaxOnly, scope, onAbort) {
}
model
类define(["cModel"], function(cModel) {
})
cModel
var _GetWayModel = new cBase.Class(cModel, {
__propertys__: function() {
var urlinfo = {
test: {
domain: 'gateway.m.fws.qa.nt.ctripcorp.com',
path: 'restapi/soa2/10419/json/'
},
pro: {
domain: 'm.ctrip.com',
path: 'restapi/soa2/10419/json/'
}
};
this.baseurl = getBaseUrl(urlinfo);
this.param = {};
},
initialize: function($super, options) {
$super(options);
},
/**
* 重写_buildurl函数
* @return {String} 构建后的url
*/
_buildurl: function() {
return this.protocol + '://' + this.baseurl.domain + '/' + this.baseurl.path + (typeof this.url === 'function' ? this.url() : this.url) + util.paramStringify(this.param);
},
/**
* 重写excute,因为经常需要同时在success和error函数里写hideloading操作,所以添加onalways
* @param {Fun} onsuccess 执行成功的操作
* @param {Fun} onerror 执行失败的操作
* @param {Fun} onalways 无论成功与否都执行的
* @param {Obj} self 上下文
*/
mallExcute: function(onsuccess, onerror, onalways, self) {
this.excute(function(json) {
onalways && onalways();
onsuccess && onsuccess(json);
}, function(error) {
onalways && onalways();
onerror && onerror(error);
}, false, self);
}
});
cStore
类中封装了一系列操作localStorage
的常用方法.
localStorage
是一个HTML5
中提供的新的没有时间限制的客户端存储数据的方法.
H5还提供了sessionStorage
用于对session
进行数据存储.
在此之前这些都是用cookie
来完成的,但是cookie
有些局限性,如不适合大量数据的存储,效率不高等~
使用localStorage
可以避免cookie
的这些缺陷.
cStore
中的一些基本参数
this.key = this.NULL;
/**
* @member lifeTime
* @type {String}
* @description 数据存活时间, 参数传递格式为“时间+时间单位",如30M
* 时间单位有D:day,H:hour,M:minutes,S:secend,
* 如过不传递时间单位,默认时间单位为M
*/
this.lifeTime = '30M';
cStore
中的一些常用方法set: function (value, tag, oldVal) {
},
setLifeTime: function (lifeTime, override) {
},
setAttr: function (attrName, attrVal, tag) {
},
get: function (tag, oldFlag) {
},
getAttr: function (attrName, tag) {
},
getTag: function () {
},
remove: function () {
},
removeAttr: function (attrName) {
}
cStroe
store
类define(["cStore"], function(cStore) {
})
cStore
简单用法:
_ret.CustomStore = function(key, lifeTime) { //自定义
return new cBase.Class(cStore, {
__propertys__: function() {
this.key = key;
this.lifeTime = lifeTime;
},
initialize: function($super, options) {
$super(options)
}
})
};
_ret.ItemBaseInfoStore = _ret.CustomStore("MALL_ITEM_BASE_INFO", "1D");
扩展用法
_ret.LocalShoppingCartStore = new cb.Class(_base, {
__propertys__: function() {
this.key = "MALL_LOCAL_SHOPPING_CART";
this.lifeTime = "2D";
},
initialize: function($super, options) {
$super(options)
},
getNum: function(siteId) {
var num = 0,
items = this.getItems(siteId);
if (!items) {
return 0;
}
for (var i = 0; i < items.length; i++) {
num += items[i].Quantity;
};
return num;
}
})
使用cStore
来实现cModel
的接口缓存
将接口返回的数据经过处理后放入localStorage
中实现接口缓存,减少重复请求次数
execute
函数执行ajax
请求的函数
/**
* 取model数据
* @param {Function} onComplete 取完的回调函
* 传入的第一个参数为model的数第二个数据为元数据,元数据为ajax下发时的ServerCode,Message等数
* @param {Function} onError 发生错误时的回调
* @param {Boolean} ajaxOnly 可选,默认为false当为true时只使用ajax调取数据
* @param {Boolean} scope 可选,设定回调函数this指向的对象
* @param {Function} onAbort 可选,但取消时会调用的函数
*/
function execute(onComplete, onError, scope, onAbort, params) {
// @description 定义是否需要退出ajax请求
this.isAbort = false;
// @description 请求数据的地址
var url = this.buildurl();
var self = this;
var __onComplete = $.proxy(function(data) {
//保存服务请求日志
// cLog.serverLog(self.buildurl(), self.getParam(), data);
if (this.validates && this.validates.length > 0) {
// @description 开发者可以传入一组验证方法进行验证
for (var i = 0, len = this.validates.length; i < len; i++) {
if (!this.validates[i](data)) {
// @description 如果一个验证不通过就返回
if (typeof onError === 'function') {
return onError.call(scope || this, data);
} else {
return false;
}
}
}
}
// @description 对获取的数据做字段映射
var datamodel = typeof this.dataformat === 'function' ? this.dataformat(data) : data;
if (typeof this.onBeforeCompleteCallback === 'function') {
this.onBeforeCompleteCallback(datamodel);
}
if (typeof onComplete === 'function') {
onComplete.call(scope || this, datamodel, data);
}
}, this);
var __onError = $.proxy(function(e) {
//保存服务请求日志
// cLog.serverLog(self.buildurl(), self.getParam());
if (self.isAbort) {
self.isAbort = false;
if (typeof onAbort === 'function') {
return onAbort.call(scope || this, e);
} else {
return false;
}
}
if (typeof onError === 'function') {
onError.call(scope || this, e);
}
}, this);
// @description 从this.param中获得数据,做深copy
var params = params || _.clone(this.getParam() || {});
//设置contentType无效BUG,改动一,将contentType保存
params.contentType = this.contentType;
if (this.contentType === AbstractModel.CONTENT_TYPE_JSON) {
// @description 跨域请求
return this.ajax = cAjax.cros(url, this.method, params, __onComplete, __onError);
} else if (this.contentType === AbstractModel.CONTENT_TYPE_JSONP) {
// @description jsonp的跨域请求
return this.ajax = cAjax.jsonp(url, params, __onComplete, __onError);
} else {
// @description 默认post请求
return this.ajax = cAjax.post(url, params, __onComplete, __onError);
}
}
excute
函数对execute
的封装
将head信息添加到request中,并添加了接口缓存以及缓存数据tag判断等功能
/**
* 取model数据
* @param {Function} onComplete 取完的回调函
* 传入的第一个参数为model的数第二个数据为元数据,元数据为ajax下发时的ServerCode,Message等数
* @param {Function} onError 发生错误时的回调
* @param {Boolean} ajaxOnly 可选,默认为false当为true时只使用ajax调取数据
* @param {Boolean} scope 可选,设定回调函数this指向的对象
* @param {Function} onAbort 可选,但取消时会调用的函数
*/
function excute(onComplete, onError, ajaxOnly, scope, onAbort) {
var params = _.clone(this.getParam() || {});
//验证错误码,并且设置新的auth
this.pushValidates(function(data) {
var curhead = this.head.get();
//兼容soa2.0 和 restful api
var rsphead = this._getResponseHead(data);
/* if (this.contentType !== AbstractModel.CONTENT_TYPE_JSONP && this.usehead && rsphead.auth && rsphead.auth !== curhead.auth) {
this.head.setAuth(rsphead.auth);
}*/
return rsphead.success;
// var head = data.head;
// if (this.contentType !== AbstractModel.CONTENT_TYPE_JSONP && this.usehead && head.auth && head.auth !== curhead.auth) {
// this.head.setAuth(head.auth);
// }
// if (head && head.errcode === 0) {
// return true;
// } else {
// return false;
// }
});
// @description 业务相关,获得localstorage的tag
var tag = this.getTag();
// @description 业务相关,从localstorage中获取上次请求的数据缓存
var cache = this.result && this.result.get(tag);
if (!cache || this.ajaxOnly || ajaxOnly) {
if (this.method.toLowerCase() !== 'get' && this.usehead && this.contentType !== AbstractModel.CONTENT_TYPE_JSONP) {
// this.setParam('head', this.head.get())
params.head = this.head.get();
params.head.time = (new Date()).getTime();
} else if (this.method.toLowerCase() !== 'get' && !this.usehead && this.contentType !== AbstractModel.CONTENT_TYPE_JSONP) {
if (this.headinfo) {
// this.setParam('head', this.headinfo);
params.head = this.headinfo;
}
}
this.onBeforeCompleteCallback = function(datamodel) {
if (this.result instanceof AbstractStore) {
//soa 数据量大,为精简locastorage,去掉ResponseStatus部分 shbzhang 2014.4.17
try {
// if(datamodel.ResponseStatus){
// delete datamodel.ResponseStatus;
// }
} catch (e) {
}
this.result.set(datamodel, tag);
}
}
this.execute(onComplete, onError, scope, onAbort, params)
} else {
if (typeof onComplete === 'function') {
onComplete.call(scope || this, cache);
}
}
}
定义store
_ret.TestStore = _ret.CustomStore("MALL_LIZARD_STORE_TEST", "1D");
定义model
_ret.getLocationList = new cBase.Class(_GetWayModel, {
__propertys__: function() {
this.url = 'GetCountrySubSiteInfoListData';
this.result = Store.TestStore.getInstance();
}
})
使用
getLocationListModel.setParam(request);
getLocationListModel.excute();