JS模板實(shí)現(xiàn)方法
概述
我們?cè)谑褂肑S渲染DOM時(shí),一般使用字符串創(chuàng)建DOM然后附加到父元素上,如果附加的DOM是動(dòng)態(tài)易變的,那需要在函數(shù)中寫大量邏輯。如果在控件實(shí)現(xiàn)過(guò)程中,這帶來(lái)的問(wèn)題更為嚴(yán)重。
解決這個(gè)問(wèn)題的常見(jiàn)解決方案是是使用模板,作為配置項(xiàng)傳入控件,實(shí)現(xiàn)數(shù)據(jù)和渲染的分離。具體的實(shí)現(xiàn)方法有以下方法:
- 字符串替換,使用正則匹配將數(shù)據(jù)替換進(jìn)字符串中。
- 渲染函數(shù),函數(shù)返回字符串。
- 模板引擎,可以將執(zhí)行字符串中的函數(shù)(內(nèi)置或者自定義的)
替換(Substitute)
字符串替換是最簡(jiǎn)單的實(shí)現(xiàn)模板的方式,看一下具體的實(shí)現(xiàn):
1. 定義替換函數(shù)
/**
* 替換字符串中的字段.
* @param {String} str 模版字符串
* @param {Object} o json data
* @param {RegExp} [regexp] 匹配字符串的正則表達(dá)式
*/
function substitute(str,o,regexp){
return str.replace(regexp || /\\?\{([^{}]+)\}/g, function (match, name) {
return (o[name] === undefined) ? '' : o[name];
});
}
2.使用配置項(xiàng):
var config = {
data : {value : '123',text:'abc'},
template : '<label>{text}</label><input type="text" value="{value}"/>'
};
3. 在創(chuàng)建DOM的過(guò)程中我們這樣調(diào)用:
var str = substitute(template,data);
$(str).appendTo('body');
通過(guò)以上示例,我們就完成了數(shù)據(jù)和字符串的解耦,可以靈活的用在控件中,當(dāng)前大多數(shù)JS框架都提供了此種方式的模板。
在此基礎(chǔ)上可以有下面的擴(kuò)展,感興趣的可以自己去實(shí)現(xiàn):
1. 使用數(shù)字代替參數(shù)名:
如 '<label>{0}</label><input type="text" value="{1}"/>'
2. 嵌套使用對(duì)象屬性:
如 '<label>{obj.name}</label><input type="text" value="{obj.value}"/>'
優(yōu)點(diǎn):實(shí)現(xiàn)簡(jiǎn)單,易于理解。
缺點(diǎn):只能進(jìn)行簡(jiǎn)單的數(shù)據(jù)結(jié)構(gòu),無(wú)法處理循環(huán)、條件語(yǔ)句。
渲染方法(Render)
我們可以在渲染函數(shù)中處理非常復(fù)雜的邏輯,可以將渲染函數(shù)作為參數(shù)傳入配置項(xiàng)。
配置項(xiàng):
var config = {
data : [{value : '0',text:'abc'},{value : '1',text:'bcd'}],
renderer : function(obj){
if(obj.value === '0'){
return obj.text;
}else{
return '<img title="' + obj.text + '" src=""/>';
}
}
};
在使用時(shí):
for(var i = 0 ; i< data.length; i++){
var obj = data[i],
str = config.renderer(obj);
$(str).appendTo('body');
}
在處理循環(huán),條件語(yǔ)句時(shí),這是一種很好的解決方案。
優(yōu)點(diǎn):實(shí)現(xiàn)相對(duì)簡(jiǎn)單,實(shí)現(xiàn)靈活,能滿足復(fù)雜數(shù)據(jù)結(jié)構(gòu),易于調(diào)試
缺點(diǎn):
- 渲染函數(shù)作為配置項(xiàng),不易理解。
- 函數(shù)較長(zhǎng)時(shí),使配置項(xiàng)臃腫。
- 每個(gè)場(chǎng)景都需要自己實(shí)現(xiàn)渲染函數(shù)。
模板引擎(XTemplate)
每一個(gè)JS UI庫(kù)都會(huì)有一個(gè)功能強(qiáng)大的模板引擎,一個(gè)模板引擎需要實(shí)現(xiàn)以下功能:
1. 字符串替換
2. 處理復(fù)雜語(yǔ)句 條件、循環(huán)
3. 使用內(nèi)嵌函數(shù)
4. 允許用戶傳入自定義函數(shù)
目前的模板引擎有2種常見(jiàn)的實(shí)現(xiàn)方式:
1. 使用正則分析字符串,執(zhí)行其中的特殊語(yǔ)句邏輯,替換對(duì)應(yīng)的數(shù)據(jù)
我們來(lái)看一下KISSY 模板的一個(gè)實(shí)例:
'Hello, {{#each users}}{{#if _ks_value.show}}{{_ks_value.name}}{{/if}}{{/each}}.'
上面這是一個(gè)模板,可以處理循環(huán)、條件語(yǔ)句。
2. 對(duì)字符串進(jìn)行語(yǔ)法分析,生成語(yǔ)法樹,執(zhí)行替換對(duì)應(yīng)的標(biāo)簽或數(shù)據(jù)。
下面是Ext的 xtemplate使用方式:
var tpl = new Ext.XTemplate(
'<p>{name}\'s favorite beverages:</p>',
'<tpl for="drinks">',
'<div> - {.}</div>',
'</tpl>'
);
tpl.overwrite(panel.body, data);
優(yōu)點(diǎn):功能強(qiáng)大,靈活性高
缺點(diǎn):使用復(fù)雜,更加不易理解。不便于調(diào)試。
問(wèn)題思考
1. 控件中使用模板,可以將數(shù)據(jù)和DOM分離,但是如果一個(gè)控件中包含大量的模板,會(huì)增加使用者的工作量,而且不易于調(diào)試,需要權(quán)衡使用。
2. 如果大量控件使用相同的模板,和相同的數(shù)據(jù)結(jié)構(gòu),每個(gè)控件單獨(dú)配置不便于使用,更好的方案是允許父控件配置模板。
- JavaScript模板引擎應(yīng)用場(chǎng)景及實(shí)現(xiàn)原理詳解
- JavaScript構(gòu)建自己的模板小引擎示例
- JavaScript模板引擎Template.js使用詳解
- JS Excel讀取和寫入操作(模板操作)實(shí)現(xiàn)代碼
- Underscore.js 的模板功能介紹與應(yīng)用
- javascript輕量級(jí)模板引擎juicer使用指南
- NodeJS框架Express的模板視圖機(jī)制分析
- 詳解JavaScript ES6中的模板字符串
- 基于jQuery的AJAX和JSON實(shí)現(xiàn)純html數(shù)據(jù)模板
- Node.js的Web模板引擎ejs的入門使用教程
- JavaScript模板引擎實(shí)現(xiàn)原理實(shí)例詳解
相關(guān)文章
微信小程序 動(dòng)態(tài)綁定數(shù)據(jù)及動(dòng)態(tài)事件處理
這篇文章主要介紹了微信小程序 動(dòng)態(tài)綁定數(shù)據(jù)及動(dòng)態(tài)事件處理的相關(guān)資料,需要的朋友可以參考下2017-03-03JavaScript原生xmlHttp與jquery的ajax方法json數(shù)據(jù)格式實(shí)例
這篇文章主要介紹了JavaScript原生xmlHttp與jquery的ajax方法json數(shù)據(jù)格式實(shí)例的相關(guān)資料,需要的朋友可以參考下2015-12-12bootstrap table.js動(dòng)態(tài)填充單元格數(shù)據(jù)的多種方法
這篇文章主要為大家詳細(xì)介紹了bootstrap table.js填充單元格數(shù)據(jù)的多種方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-07-07Javascript的表單驗(yàn)證-初識(shí)正則表達(dá)式
JavaScript 可用來(lái)在數(shù)據(jù)被送往服務(wù)器前對(duì) HTML 表單中的這些輸入數(shù)據(jù)進(jìn)行驗(yàn)證。接下來(lái)通過(guò)本文給大家介紹Javascript的表單驗(yàn)證-初識(shí)正則表達(dá)式,對(duì)js表單驗(yàn)證正則表達(dá)式相關(guān)知識(shí)感興趣的朋友一起學(xué)習(xí)吧2016-03-03包含中國(guó)城市的javascript對(duì)象實(shí)例
這篇文章主要介紹了包含中國(guó)城市的javascript對(duì)象,以一個(gè)javascript的json數(shù)據(jù)格式存儲(chǔ)為例分析了javascript存儲(chǔ)城市信息的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-08-08分享Bootstrap簡(jiǎn)單表格、表單、登錄頁(yè)面
本文給大家分享Bootstrap簡(jiǎn)單表格、表單、登錄頁(yè)面的實(shí)例代碼,非常不錯(cuò),具有參考借鑒價(jià)值,需要的的朋友參考下吧2017-08-08微信小程序與公眾號(hào)實(shí)現(xiàn)數(shù)據(jù)互通的方法
這篇文章主要介紹了微信小程序與公眾號(hào)實(shí)現(xiàn)數(shù)據(jù)互通的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07javascript實(shí)現(xiàn)二叉樹遍歷的代碼
這篇文章主要介紹了javascript實(shí)現(xiàn)二叉樹遍歷的代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06javascript實(shí)現(xiàn)信息增刪改查的方法
這篇文章主要介紹了javascript實(shí)現(xiàn)信息增刪改查的方法,實(shí)例分析了javascript操作頁(yè)面元素實(shí)現(xiàn)針對(duì)頁(yè)面信息的增刪改查功能,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-07-07