问题:在Meteor开发时,添加一个Loading的功能(即使运行Meteor.call显示和隐藏loading overlay)在Meteor.call的生命周期上。
不多解释,直接上代码。本人刚入门不久,可能这个方案比较土,不过在有更好的方法之前这个还是挺有用的。码友们可以试试,如果发现BUG,ISSUE 或者 New idea,别忘了跟帖分享哦!
有个前提,这里 我已经封装了一个叫 loading 的全局对象,目的就是 loading.pleaseWait() 和 loading.done() 来显示和隐藏 loading overlay。这个逻辑不是本文重点,跳过。
上代码:(文件:
new file: client/lib/meteorWrap.js
)/**
* @author: wang xiaoqiang
* @date: Aug 21, 2015
*/
(function(Meteor) {
var _call = Meteor.call;
Meteor.call = function() {
/* wrapper for loading module */
if(typeof loading !== 'undefined') loading.pleaseWait();
var _arguments = arguments;
var _callback;
if (typeof arguments[arguments.length - 1] === 'function') {
_callback = arguments[arguments.length - 1];
_arguments = Array.prototype.slice.call(arguments, 0, -1);
_arguments.push(function(err, result) {
_callback(err, result);
setTimeout(function(){
if(typeof loading !== 'undefined') loading.done();
}, 200);
});
}
var req = _call.apply(Meteor, _arguments);
return req;
};
})(Meteor);
另外一种写法就是利用 underscore 来完成:
var NAME = 'meteorWrap';
['Meteor', '_', 'loading'].forEach(function(ind, dep) {
if (typeof _ === 'undefined') {
throw new Meteor.Error(NAME, dep + ' is required by ' + NAME + '.');
}
});
Meteor.call = _.wrap(Meteor.call, function(meteor_call) {
// BEFORE
// wrapper for loading module
loading.pleaseWait();
var args = [].slice.call(arguments, 1, -1), cb = arguments[arguments.length - 1];
[].push.call(args, function(cb){ // process last argument
return typeof cb !== 'function' ? cb : _.wrap(cb, function(cbo) {
var res = cbo.apply(cbo, [].slice.call(arguments, 1));
loading.done();
return res;
});
}(cb));
// DOING
return meteor_call.apply(Meteor, args);
});