任務原因,下周要實現一個模塊,為瞭能提高效率,我做瞭一個通用工具類,其實也是在原基礎上改的
以前的版本支持${..}這種樣子的替換 比如
<p style="display:${display}">…
替換為
<p style="display:none">…
有些比如時間格式化和判斷之類就必須在代碼處理好瞭之後在將值傳給模板,但格式化和判斷邏輯基本都是一致的,於是我想這些直接通過視圖模板就處理好些問題
$date:時間格式化
<span>$date{day,YY MM DD}</span>
替換為
<span>11 11 11</span>
$pick:三目運算
<span>$pick{age,25,好年輕,好老啊}</span>
替換為(age = 24)
<span>好年輕</span>
模板如果想處理更靈活,需要對嵌套的情況做下處理 比如:
<span>$pick{age,${age2},${msg1},${msg2}}</span>
替換為(age = 24,age2 = 25 , msg1 = 好年輕 ,msg2 = 好老啊)
<span>好年輕</span>
有時候模板需要過濾掉${..},可能真正輸出就是這種格式,怎麼辦?加上"\\"
<span>$pick{age,${age2},\\${msg1},${msg2}}</span>
替換為(age = 24,age2 = 25 , msg1 = 好年輕 ,msg2 = 好老啊)
<span>${msg1}</span>
Javascript代碼
function extends(objOld,objNew){
for(var n in objNew){
if(objNew.hasOwnProperty(n)){
objOld[n] = objNew[n];
}
}
}
Template = function(){
this.initialize(arguments[0]);
};
Template.prototype = {
initialize: function (template,opt) {
this.template = template + '';
//對\\進行過濾
this.filter = "\\\\";
//format:arguments[3],arguments[4]
//pic:arguments[5],arguments[6],arguments[7],arguments[8]
//defalut:arguments[9]
//獲取參數
this.regPattern = /(^|[\s\S])(\$date\{([^,]*?),([^}]*?)\}|\$pick\{([^,]*?),([^,]*?),([^,]*?),([^}]*?)\}|\$\{([^}]*?)\})/g;
//是否嵌套
this.isNesting = /(?:^|[\s\S])\$[^{]*?\{[^}]*?(?=\$[^{]*?\{[^}]*?\})/g;
extends(this,opt);
},
evaluate: function (obj) {
var _template = "";
if (typeof obj == "object") {
var _this = this;
_template = this.template.replace(this.regPattern, function (s, v1, v2) {
if(_this.isNesting.test(s)){
for(var i = arguments.callee.length ; i < arguments.length – 2 ;i ++){
if(arguments[i]){
arguments[i] = arguments[i].replace(_this.regPattern, arguments.callee);
}
}
}
if(new RegExp("^" + _this.filter,"").test(v1)){
return v1 + v2;
}else{
if(/^\$\{/.test(v2)){
return v1 + (obj[arguments[9]] || "");
}
if(/^\$date\{/.test(v2)){
//2011-08-26 16:10:06
return v1 + (obj[arguments[3]] ? _this._date_format(obj[arguments[3]],arguments[4]) : "");
}
if(/^\$pick\{/.test(v2)){
return v1 + (obj[arguments[5]] ? (obj[arguments[5]] == arguments[6] ? arguments[7] : arguments[8]) : "");
}
}
});
}
return _template;
},
//YY/YYYY MM DD hh mm ss
_date_format : function(datestr,reg){
var tmp = datestr.split(" ");
var ymd = tmp[0];
var hms = tmp[1];
tmp = ymd.split("-");
var Y = tmp[0];
var M = tmp[1];
var D = tmp[2];
tmp = hms.split(":");
var h = tmp[0];
var m = tmp[1];
var s = tmp[2];
reg = reg || "hh:mm:ss";
/\bss\b/.test(reg) && (reg = reg.replace(/\bss\b/,s));
/\bmm\b/.test(reg) && (reg = reg.replace(/\bmm\b/,m));
/\bhh\b/.test(reg) && (reg = reg.replace(/\bhh\b/,h));
/\bMM\b/.test(reg) && (reg = reg.replace(/\bMM\b/,M));
/\bDD\b/.test(reg) && (reg = reg.replace(/\bDD\b/,D));
/\bYYYY\b/.test(reg) && (reg = reg.replace(/\bYYYY\b/,Y));
/\bYY\b/.test(reg) && (reg = reg.replace(/\bYYYY\b/,Y.substring(2)));
return reg;
}
};
var str2 = '$date{ddd,mm:ss}asdfjakjsdlkfjkl<<><{}werwesdf$ {} sdfer $${display} $pick{vid,${vid},11,22}';
var t = new Template(str2);
var respance = t.evaluate({vid:"123123123",ddd:"2011-08-26 16:10:06",display:"true"});
alert(respance);
//更改前:
//$date{ddd,mm:ss}asdfjakjsdlkfjkl<<><{}werwesdf$ {} sdfer $${display} $pick{vid,${vid},11,22}
//更改後:
//10:06asdfjakjsdlkfjkl<<><{}werwesdf$ {} sdfer $true 11
需要修改過濾字符new Template(str2,{filter:"$"})
this.regPattern可以分為三段來看
\$\{([^}]*?)\}
處理最普通的情況${…}
\$pick\{([^,]*?),([^,]*?),([^,]*?),([^}]*?)\}
處理三目運算,裡面獲取4個參數
\$date\{([^,]*?),([^}]*?)\}
處理時間格式化,獲取裡面2個參數
(^|[\s\S])
[\s\S] 匹配任意字符,包含\r,\t ,還包括開頭
這正則幹瞭這麼兩件事:
1)獲取$前面的一個字符,如果是開頭則不取,用來判斷是否過濾
2)獲取普通,時間格式化,三目運算的參數
擴展:
添加對應正則,添加對應的處理策略