java调用js模板引擎_JavaScript模板引擎应用场景及实现原理详解

本文详细介绍了JavaScript模板引擎的应用场景,如动态数据展现、代码书写效率提升等,并以artTemplate为例,阐述了模板的存放、解析、编译过程,以及如何装载数据呈现视图。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文实例讲述了JavaScript模板引擎应用场景及实现原理。分享给大家供大家参考,具体如下:

一、应用场景

以下应用场景可以使用模板引擎:

1、如果你有动态ajax请求数据并需要封装成视图展现给用户,想要提高自己的工作效率。

2、如果你是拼串族或者数组push族,迫切的希望改变现有的书写方式。

3、如果你在页面布局中,存在共性模块和布局,你可以提取出公共模板,减少维护的数量。

二、实现原理

不同模板间实现原理大同小异,各有优缺,请按需选择,以下示例以artTemplate模板引擎来分析。

2.1 模板存放

模板一般都是放置到textarea/input等表单控件,或者script[type="text/html"]等标签中,如下:

{{if isAdmin}}

{{title}}

{{each user as name i}}

{{i + 1}} :{{name}}

{{/each}}

{{/if}}

//textarea或input则取value,其它情况取innerHTML

2.2 模板函数

一般都是templateFun("id", data);其中id为存放模板字符串的元素id,data为需要装载的数据。

2.3 模板获取

一般都是通过ID来获取,document.getElementById("ID"):

//textarea或input则取value,其它情况取innerHTML

var html = /^(textarea|input)$/i.test(element.nodeName) ? element.value : element.innerHTML;

2.4 模板解析——处理html语句和逻辑语句及其他格式化处理

这步的主要操作其实多余的空格,解析出html元素和逻辑语句及关键字。例如:artTemplate.js中的代码实现:

defaults.parser = function (code, options) {

// var match = code.match(/([\w\$]*)(\b.*)/);

// var key = match[1];

// var args = match[2];

// var split = args.split(' ');

// split.shift();

//if isAdmin

code = code.replace(/^\s/, '');

//["if", "isAdmin"]

var split = code.split(' ');

//if

var key = split.shift();

//isAdmin

var args = split.join(' ');

switch (key) {

case 'if':

//if(isAdmin){

code = 'if(' + args + '){';

break;

case 'else':

if (split.shift() === 'if') {

split = ' if(' + split.join(' ') + ')';

} else {

split = '';

}

code = '}else' + split + '{';

break;

case '/if':

code = '}';

break;

case 'each':

var object = split[0] || '$data';

var as = split[1] || 'as';

var value = split[2] || '$value';

var index = split[3] || '$index';

var param = value + ',' + index;

if (as !== 'as') {

object = '[]';

}

code = '$each(' + object + ',function(' + param + '){';

break;

case '/each':

code = '});';

break;

case 'echo':

code = 'print(' + args + ');';

break;

case 'print':

case 'include':

code = key + '(' + split.join(',') + ');';

break;

例如上例中:”{{if isAdmin}}”最终被解析成”if(isAdmin){”,”{{/if}}“被解析成“}”。

2.5 模板编译——字符串拼接成生成函数的过程

这步的主要操作就是字符串的拼接成生成函数,看看artTemplate的部分源码:

function compiler (source, options) {

/*

openTag: '

closeTag: '%>', // 逻辑语法结束标签

escape: true, // 是否编码输出变量的 HTML 字符

cache: true, // 是否开启缓存(依赖 options 的 filename 字段)

compress: false, // 是否压缩输出

parser: null // 自定义语法格式器 @see: template-syntax.js

*/

var debug = options.debug;

var openTag = options.openTag;

var closeTag = options.closeTag;

var parser = options.parser;

var compress = options.compress;

var escape = options.escape;

var line = 1;

var uniq = {$data:1,$filename:1,$utils:1,$helpers:1,$out:1,$line:1};

//isNewEngin在6-8返回undefined

var isNewEngine = ''.trim;// '__proto__' in {}

var replaces = isNewEngine

? ["$out='';", "$out+=", ";", "$out"]

: ["$out=[];", "$out.push(", ");", "$out.join('')"];

var concat = isNewEngine

? "$out+=text;return $out;"

: "$out.push(text);";

var print = "function(){"

+ "var text=''.concat.apply('',arguments);"

+ concat

+ "}";

var include = "function(filename,data){"

+ "data=data||$data;"

+ "var text=$utils.$include(filename,data,$filename);"

+ concat

+ "}";

var headerCode = "'use strict';"

+ "var $utils=this,$helpers=$utils.$helpers,"

+ (debug ? "$line=0," : "");

var mainCode = replaces[0];

var footerCode = "return new String(" + replaces[3] + ");"

// html与逻辑语法分离

forEach(source.split(openTag), function (code) {

code = code.split(closeTag);

var $0 = code[0];

var $1 = code[1];

// code: [html]

if (code.length === 1) {

mainCode += html($0);

// code: [logic, html]

} else {

mainCode += logic($0);

if ($1) {

mainCode += html($1);

}

}

});

var code = headerCode + mainCode + footerCode;

上例中模板中的模板字符串代码会被拼接成如下字符串:

'use strict';

var $utils = this,

$helpers = $utils.$helpers,

isAdmin = $data.isAdmin,

$escape = $utils.$escape,

title = $data.title,

$each = $utils.$each,

user = $data.user,

name = $data.name,

i = $data.i,

$out = '';

if (isAdmin) {

$out += '\n\n

';

$out += $escape(title);

$out += '\n

  • \n ';

$each(user, function(name, i) {

$out += '\n

';

$out += $escape(i + 1);

$out += ' :';

$out += $escape(name);

$out += '

\n ';

});

$out += '\n

\n\n ';

}

return new String($out);

然后会被生成如下函数:

var Render = new Function("$data", "$filename", code);

/*Outputs:

function anonymous($data, $filename) {

'use strict';

var $utils = this,

$helpers = $utils.$helpers,

isAdmin = $data.isAdmin,

$escape = $utils.$escape,

title = $data.title,

$each = $utils.$each,

user = $data.user,

name = $data.name,

i = $data.i,

$out = '';

if (isAdmin) {

$out += '\n\n

';

$out += $escape(title);

$out += '\n

  • \n ';

$each(user, function(name, i) {

$out += '\n

';

$out += $escape(i + 1);

$out += ' :';

$out += $escape(name);

$out += '

\n ';

});

$out += '\n

\n\n ';

}

return new String($out);

}

*/

console.log(Render);

2.5 装载数据,视图呈现

/*Outputs:

User lists

  • 1 :zuojj
  • 2 :Benjamin
  • 3 :John
  • 4 :Rubby
  • 5 :Handy
  • 6 :CIMI

*/

console.log(new Render(data, filename) + '');

//对象转换为字符串

return new Render(data, filename) + '';

三、常见JavaScript模板引擎及测试对比

希望本文所述对大家JavaScript程序设计有所帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值