这里插一句监控的问题,因为前端代码压缩后,js错误监控变得不太靠谱,而前端的错误有很大可能是搬运数据过程中出了问题,所以在请求model层做对应的数据校验是十分有意义的 如果发现数据不对便发错误日志,好过被用户抓住投诉,而这里做数据校验也为模板中使用数据做了基础检查
服务器端给前端的数据可能是松散的,前端真实使用时候会对数据做处理,同一请求模块如果在不同地方使用,就需要多次处理,这个是不需要的,比如:
(data.a) ... if(data.a.b) ...
这里我说下blade框架中请求模块的处理:
blade的请求模块我们现在站点主要还是源于blade框架,实际使用时候做了点改变,后续会回归到blade框架,项目目录结构为:
其中store依赖于storage模块,是处理localstorage缓存的,他与model是独立的,以下为核心代码:
1 define([], function () { Model = _.inherit({ propertys: function () { 6 this.protocol = 'http'; 7 this.domain = ''; 8 this.path = ''; 9 this.url = null; 10 this.param = {}; 11 this.validates = []; .ajaxOnly = true; .contentType = 'application/x-www-form-urlencoded'; 17 this.type = 'GET'; 18 this.dataType = 'json'; 19 }, 20 21 setOption: function (options) { 22 _.extend(this, options); 23 }, 24 25 assert: function () { 26 if (this.url === null) { 27 throw 'not override url property'; 28 } 29 }, 30 31 initialize: function (opts) { 32 this.propertys(); 33 this.setOption(opts); 34 this.assert(); 35 36 }, 37 38 pushValidates: function (handler) { 39 if (typeof handler === 'function') { 40 this.validates.push($.proxy(handler, this)); 41 } 42 }, 43 44 setParam: function (key, val) { 45 if (typeof key === 'object') { 46 _.extend(this.param, key); 47 } else { 48 this.param[key] = val; 49 } 50 }, 51 52 removeParam: function (key) { .param[key]; 54 }, 55 56 getParam: function () { .param; 58 }, buildurl: function () { "[ERROR]abstract method:buildurl, must be override"; 65 66 }, 67 68 onDataSuccess: function () { 69 }, * 72 * 取model数据 73 * @param {Function} onComplete 取完的回调函 74 * 传入的第一个参数为model的数第二个数据为元数据,元数据为ajax下发时的ServerCode,Message等数 75 * @param {Function} onError 发生错误时的回调 76 * @param {Boolean} ajaxOnly 可选,默认为false当为true时只使用ajax调取数据 77 * @param {Boolean} scope 可选,设定回调函数this指向的对象 78 * @param {Function} onAbort 可选,但取消时会调用的函数 execute: function (onComplete, onError, ajaxOnly, scope) { 81 var __onComplete = $.proxy(function (data) { 82 var _data = data; 83 if (typeof data == 'string') _data = JSON.parse(data); (var i = 0, len = this.validates.length; i < len; i++) { 87 if (!this.validates[i](data)) { (typeof onError === 'function') { 90 return onError.call(scope || this, _data, data); 91 } else { ; 93 } 94 } 95 } datamodel = typeof this.dataformat === 'function' ? this.dataformat(_data) : _data; (this.onDataSuccess) this.onDataSuccess.call(this, datamodel, data); 101 if (typeof onComplete === 'function') { 102 onComplete.call(scope || this, datamodel, data); 103 } 104 105 }, this); __onError = $.proxy(function (e) { 108 if (typeof onError === 'function') { 109 onError.call(scope || this, e); 110 } 111 }, this); .sendRequest(__onComplete, __onError); 114 115 }, 116 117 sendRequest: function (success, error) { 118 var url = this.buildurl(); 119 var params = _.clone(this.getParam() || {}); 120 var crossDomain = { 121 'json': true, 122 'jsonp': true 123 }; (this.type == 'POST') { 133 this.dataType = 'json'; 134 } $.ajax({ 138 url: url, 139 type: this.type, 140 data: params, 141 dataType: this.dataType, 142 contentType: this.contentType, 143 crossDomain: crossDomain[this.dataType], 144 timeout: 50000, 145 xhrFields: { 146 withCredentials: true 147 }, 148 success: function (res) { 149 success && success(res); 150 }, 151 error: function (err) { 152 error && error(err); 153 } 154 }); 155 156 } 157 158 }); 159 160 Model.getInstance = function () { 161 if (this.instance) { .instance; 163 } else { .instance = new this(); 165 } 166 }; Model; 169 });
model