本篇體驗使用AngularJS自定義一個記錄日誌的服務。 在AngularJS中,服務的一些寫法是這樣的: var app = angular.module('app',[]); app.provider('providerName', function(){...}); app.service('
本篇體驗使用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/