arttemplate嵌套子模板,属性不存在时,取值bug与解决办法

无可置疑,arttemplate是本人用过的最好用的前端模板引擎。不过随着使用的深入与更加广泛,还是遇到了一些梗。下面将较少一个本人遇到的实际问题,分析方法与采用的解决办法。

一、问题描述

Arttemplate嵌套子模板,属性不存在时,默认值$data取值为当前父级。

<body>
<div id="demo"></div>

<!--
作者:1209461019@qq.com
时间:2017-02-17
描述:主模板
-->
<script type="text/html" id="demo_T">
{{each}}
	<div>姓名:{{$value.name}}</div>
	<div>性别:{{$value.age}}</div>
	<!--
		作者:1209461019@qq.com
		时间:2017-02-17
		描述:嵌套子模板
	-->
	<div>朋友:{{include 'demo_sub_T' $value.friends}}</div>
	<hr /> 
{{/each}}
</script>
<!--
	作者:1209461019@qq.com
	时间:2017-02-17
	描述:子模板
-->
<script type="text/html" id="demo_sub_T">
{{each}}
	<div>朋友姓名:{{$value.name}}</div>
	<div>朋友年龄:{{$value.age}}</div>
{{/each}}
</script>

<script type="text/javascript" src="js/template-debug.js"></script>
<script>
	//数据源
	var data = [{
		name: "李德涛",
		age: 36,
		friends: [{
			name: "马三立"
		}, {
			name: "冯小刚"
		}]
	}, {
		name: "狗蛋",
		age: 10
	}];
	/**
	 * <pre>
	 * 预计结果:
		姓名:李德涛
		性别:36
		朋友:
		朋友姓名:马三立
		朋友年龄:
		朋友姓名:冯小刚
		朋友年龄:
		
		姓名:狗蛋
		性别:10
		朋友:
		
	 * 实际结果:
		姓名:李德涛
		性别:36
		朋友:
		朋友姓名:马三立
		朋友年龄:
		朋友姓名:冯小刚
		朋友年龄:
		
		姓名:狗蛋
		性别:10
		朋友:
		朋友姓名:李德涛
		朋友年龄:36
		朋友姓名:狗蛋
		朋友年龄:10
	 * 
	 * 错误分析:子模板嵌套时,第二个没有friends属性,而把当前对象进行了赋值
	 * 
	 * </pre>
	 */

	//内容渲染
	var html = template('demo_T', data);
	document.getElementById('demo').innerHTML = html;
</script>
</body>

二、问题分析

错误分析:子模板嵌套时,第二个没有friends属性,而把当前对象进行了赋值。

<body>
<div id="demo"></div>

<!--
作者:1209461019@qq.com
时间:2017-02-17
描述:主模板
-->
<script type="text/html" id="demo_T">
{{each}}
	<div>姓名:{{$value.name}}</div>
	<div>性别:{{$value.age}}</div>
	<!--
		作者:1209461019@qq.com
		时间:2017-02-17
		描述:嵌套子模板
	-->
	<div>朋友:{{include 'demo_sub_T' $value.friends}}</div>
	<hr /> 
{{/each}}
</script>
<!--
	作者:1209461019@qq.com
	时间:2017-02-17
	描述:子模板
-->
<script type="text/html" id="demo_sub_T">
{{each debug($data,'子模板')}}
	<div>朋友姓名:{{$value.name}}</div>
	<div>朋友年龄:{{$value.age}}</div>
{{/each}}
</script>

<script type="text/javascript" src="js/template-debug.js"></script>
<script>
	//数据源
	var data = [{
		name: "李德涛",
		age: 36,
		friends: [{
			name: "马三立"
		}, {
			name: "冯小刚"
		}]
	}, {
		name: "狗蛋",
		age: 10
	}];
	/**
	 * <pre>
	 * 预计结果:
		姓名:李德涛
		性别:36
		朋友:
		朋友姓名:马三立
		朋友年龄:
		朋友姓名:冯小刚
		朋友年龄:
		
		姓名:狗蛋
		性别:10
		朋友:
		
	 * 实际结果:
		姓名:李德涛
		性别:36
		朋友:
		朋友姓名:马三立
		朋友年龄:
		朋友姓名:冯小刚
		朋友年龄:
		
		姓名:狗蛋
		性别:10
		朋友:
		朋友姓名:李德涛
		朋友年龄:36
		朋友姓名:狗蛋
		朋友年龄:10
	 * 
	 * 错误分析:子模板嵌套时,第二个没有friends属性,而把当前对象进行了赋值
	 * 
	 * 
	 * </pre>
	 */

	//添加自定义方法,进行子模板调试
	template.helper("debug", function(data, type) {
		console.log(type);
		console.log(JSON.stringify(data));
		
		/**
		 * <pre>
		 * 打印日志:
			demo-debug.html:100 子模板
			demo-debug.html:101 [{"name":"马三立"},{"name":"冯小刚"}]
			demo-debug.html:100 子模板
			demo-debug.html:101 [{"name":"李德涛","age":36,"friends":[{"name":"马三立"},{"name":"冯小刚"}]},{"name":"狗蛋","age":10}]
		 * 
		 * </pre>
		 */
		
		return data;
	});

	//内容渲染
	var html = template('demo_T', data);
	document.getElementById('demo').innerHTML = html;
</script>
</body>

三、问题解决

添加自定义方法,进行数据整理。

<body>
<div id="demo"></div>

<!--
作者:1209461019@qq.com
时间:2017-02-17
描述:主模板
-->
<script type="text/html" id="demo_T">
{{each}}
	<div>姓名:{{$value.name}}</div>
	<div>性别:{{$value.age}}</div>
	<!--
		作者:1209461019@qq.com
		时间:2017-02-17
		描述:嵌套子模板
	-->
	<div>朋友:{{include 'demo_sub_T' handler($value.friends)}}</div>
	<hr /> 
{{/each}}
</script>
<!--
	作者:1209461019@qq.com
	时间:2017-02-17
	描述:子模板
-->
<script type="text/html" id="demo_sub_T">
{{each}}
	<div>朋友姓名:{{$value.name}}</div>
	<div>朋友年龄:{{$value.age}}</div>
{{/each}}
</script>

<script type="text/javascript" src="js/template-debug.js"></script>
<script>
	//数据源
	var data = [{
		name: "李德涛",
		age: 36,
		friends: [{
			name: "马三立"
		}, {
			name: "冯小刚"
		}]
	}, {
		name: "狗蛋",
		age: 10
	}];
	/**
	 * <pre>
	 * 预计结果:
		姓名:李德涛
		性别:36
		朋友:
		朋友姓名:马三立
		朋友年龄:
		朋友姓名:冯小刚
		朋友年龄:
		
		姓名:狗蛋
		性别:10
		朋友:
		
	 * 实际结果:
		姓名:李德涛
		性别:36
		朋友:
		朋友姓名:马三立
		朋友年龄:
		朋友姓名:冯小刚
		朋友年龄:
		
		姓名:狗蛋
		性别:10
		朋友:
		朋友姓名:李德涛
		朋友年龄:36
		朋友姓名:狗蛋
		朋友年龄:10
	 * 
	 * 错误分析:子模板嵌套时,第二个没有friends属性,而把当前对象进行了赋值
	 * 
	 * 
	 * </pre>
	 */

	//添加自定义方法,进行数据整理
	template.helper("handler", function(data) {
		
		if(data&&data instanceof Array){
			return data;
		}else{
			return [];
		}
	});

	//内容渲染
	var html = template('demo_T', data);
	document.getElementById('demo').innerHTML = html;
</script>
</body>

四、附件地址

Demo代码:http://pan.baidu.com/s/1eS7kpVW

开源地址:https://github.com/lidetao/arttemplateDemo

© 2017, 李德涛博客. 版权所有.

发表评论

电子邮件地址不会被公开。 必填项已用*标注