Lizard 分享

Lizard 中的cModel&cStore

演讲者: 王兵兵

cModel

cModel类中封装了一系列的ajax请求的常用方法.

主要用于继承,不会单独使用.

cModel中的一些基本参数

/**
* {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";

cModel中的一些常用方法

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) {

}

使用cModel

定义一个新的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

cStore类中封装了一系列操作localStorage的常用方法.

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

使用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();

Q & A

<Thank You!>

Powered By nodePPT v0.9.5