AngularJS中实现日志服务

时间:2023-03-09 05:01:36
AngularJS中实现日志服务

本篇体验使用AngularJS自定义一个记录日志的服务。

在AngularJS中,服务的一些写法是这样的:

var app = angular.module('app',[]);

app.provider('providerName', function(){...});
app.service('serviceName', function(){});
app.factory('factoryName', function(){});

等同于:

app.config(['$provide', function($provide){
$provide.provider('providerName', function(){...});
}]) app.config(['$provide', function($provide){
$provide.service('serviceName', function(){...});
}]) app.config(['$provide', function($provide){
$provide.factory('factoryName', function(){...});
}])

而实际上,$provider.service()和$provider.factory()也可以通过$provider.provider()以注入的方式实现。

app.config(['$provide', function($provide){
$provide.service('serviceName', function(){
this.name = "";
this.author = "";
})
}])

以上等同于:

app.config(['$provide','$injector', function($provide, $injector){
$provide.provider('serviceName', function(){
this.$get = function($injector) {
return $injector.instantiate(function(){
this.name = "";
this.author = "";
});
}
});
}])

以上,也就是说,service本身就是一个provider,可以通过$injector来初始化一个service。

同理,我们这样写factory:

app.config(['$provide', function($provide){
$provide.factory('factoryName', function(){
return {name:'', author:''};
})
}])

以上等同于:

app.config(['$provide', '$injector',function($provide, $injector){
$provide.provider('factoryName', function(){
this.$get = function($injector){
return $injector.invoke(function(){
return {name:'', author:''}
})
}
})
}])

创建自己的provider

$provide.provider('appColor', function(){
var color = 'red'; this.setColor = function(newColor){
color = newColor;
} thi.$get = function(){
return color;
}
})

我们可以在config中使用appColor这个自定义的provider的方法进行一些设置。

app.config(['appColorProvider', function(appColorProvider){
appColorProvider.setColor('green');
}])

然后在run中注入appColor这个服务。

app.run(['appColor', funciton(appColor){
console.log(appColor);
}])

创建日志服务

假设需要的日志格式如下:

<timestamp> - <context>::<method name>('<message>')
<timestamp> - <context>: <message>

创建一个有关日志的类:

var Logger = function(context){
this.context = context;
} Logger.getInstance = function(context){
return new Logger(context);
} //替代
Logger.supplant = function(str, o){
return str.replace(/\{([^{}]*)\}/g, function(a, b){
var r = o[b];
return typeof r === 'string' || typeof r === 'number' ? r:a;
})
} //格式化时间
Logger.getFormattedTimestamp = funciton(date){
return Logger.supplant('{0}:{1}:{2}:{3}', [
date.getHours() ,
date.getMinutes(),
date.getSeconds(),
date.getMilleseconds()
]);
} Logger.prototype = {
_log: function(originalFn, args){
var now = Logger.getFormattedTimestamp(new Date());
var message = '', supplantDate = [];
switch(args.length){
//打印格式:<timestamp> - <context>: <message>
case 1:
message = Logger.supplant("{0} - {1}:{2}", [now, this.context, args[0]]);
break;
case 3:
//打印格式:<timestamp> - <context>::<method name>('<message>')
//第一个参数是方法名
//第二个参数是消息
//第三各参数是对象
supplantData = args[2];
message = Logger.supplant("{0} - {1}::{1}(\'{3}\')",[now, this.context, args[0], args[1]]);
break;
case 2:
//检测第二个参数类型
if(typeof args[1] === 'string'){
message = Logger.supplant("{0} - {1}::{2}(\'{3}\')",[now, this.context, args[0], args[1]]);
} else {
sup;antData = args[1];
message = Logger.supplant("{0} - {1}:{2}", [now, this.context.args[0]])
}
break;
} $log[originalFn].call(null, Logger.supplant(message, suppantData));
},
log: function(){
this._log('log', arguments);
},
info: function(){
this._log('info', arguments);
},
warn: function(){
this._log('warn', arguments);
},
debug: function(){
this._log('debug', argments);
},
error: function(){
this._log('error', arguments);
}
};

我们可能按如下使用这个日志类:

//Example是类或文件或module的名称
var logger = Logger.getInstance('Example');
logger.log('this is a alog');
logger.warn('warn', 'this is a worn');
logger.error('this is a {0} error {1}',['big','hello']);

完整代码如下:

app.provider('Logger', [function(){
var isEnabled = true;
this.enabled = function(_isEnabled){
isEnabled = !!_isEnabled;
} this.$get = ['$log', function($log){ var Logger = function(context){
this.context = context;
} Logger.getInstance = function(context){
return new Logger(context);
} //替代
Logger.supplant = function(str, o){
return str.replace(/\{([^{}]*)\}/g, function(a, b){
var r = o[b];
return typeof r === 'string' || typeof r === 'number' ? r:a;
})
} //格式化时间
Logger.getFormattedTimestamp = funciton(date){
return Logger.supplant('{0}:{1}:{2}:{3}', [
date.getHours() ,
date.getMinutes(),
date.getSeconds(),
date.getMilleseconds()
]);
} Logger.prototype = {
_log: function(originalFn, args){
if(!isEnabled){
return;
} var now = Logger.getFormattedTimestamp(new Date());
var message = '', supplantDate = [];
switch(args.length){
//打印格式:<timestamp> - <context>: <message>
case 1:
message = Logger.supplant("{0} - {1}:{2}", [now, this.context, args[0]]);
break;
case 3:
//打印格式:<timestamp> - <context>::<method name>('<message>')
//第一个参数是方法名
//第二个参数是消息
//第三各参数是对象
supplantData = args[2];
message = Logger.supplant("{0} - {1}::{1}(\'{3}\')",[now, this.context, args[0], args[1]]);
break;
case 2:
//检测第二个参数类型
if(typeof args[1] === 'string'){
message = Logger.supplant("{0} - {1}::{2}(\'{3}\')",[now, this.context, args[0], args[1]]);
} else {
sup;antData = args[1];
message = Logger.supplant("{0} - {1}:{2}", [now, this.context.args[0]])
}
break;
} $log[originalFn].call(null, Logger.supplant(message, suppantData));
},
log: function(){
this._log('log', arguments);
},
info: function(){
this._log('info', arguments);
},
warn: function(){
this._log('warn', arguments);
},
debug: function(){
this._log('debug', argments);
},
error: function(){
this._log('error', arguments);
}
}; return Logger;
}]
}])

在全局关闭自定义的Logger。

app.config(['LoggerProvider', function(LoggerProvider){
LoogerProvider.enabled(false);
}])

参考:http://www.webdeveasy.com/service-providers-in-angularjs-and-logger-implementation/