mustache 渲染列表项 index

来源:互联网 发布:2016域名价格排行榜 编辑:程序博客网 时间:2024/05/21 22:42

一、模板介绍

1.简单介绍

mustache是一种无逻辑的模板引擎,用于将数据渲染到模板上,然后可以将渲染过后的结构输出到任何地方,HTML、File……。官方GitHub。
mustache是通过一种上下文环境(Context)将数据渲染到模板上。

2.Context简单说明

Context对应着数据对象本身,一开始的时候 Context 对应的就是传递的整个数据。当渲染列表时,Context的指向就会发生变化,每渲染到列表的某一项时,Context 就指向某一项的数据,同时内部的parent指针,着缓存着,上一级的Context。每次渲染数据时,先从当前的 Context指针上根据 key 去寻找对应的 value,如果当前 Context 指针没有对应的 key,则到上一级 Context 去匹配数据,依次类推。其实整个 Context 的模式就对应着数据的层级结构。

3.简单使用

使用都比较简单,常用的指令就只有几个, {{ }}、{{{ }}}、{{@ }}、{{# }}{{/ }}、{{^ }}{{/ }};下面直接贴出代码,在代码的注释里有一些注意事项。
模板:
<!-- 为了方便, 将模板放入到一个 script 节点下面 --><script id="demoTpl" type="x-tmpl-mustache">{{ id }} --{{! 这个是mustache注释指令:如果有 name 这渲染 name }}{{#name}}{{ name }}{{/name}} --{{#adult}}已成年{{/adult}}{{^adult}}未成年{{/adult}}<br>{{^subdata}}没有 subdata 数据{{/subdata}}<ul>{{#subdata}}<li>{{ id }} -- {{ title }} -- {{ desc }}</li>{{/subdata}}</ul></script>
数据以及渲染:
var data = {d: 1,name: 'name',age: 20,subdata: [{title: '数据1',desc: '数据描述1'}, {title: '数据2',desc: '数据描述2'}],/* 以下可以通过 函数 控制 if|for 逻辑 *//*{{^}} 指令用于判断的是:不存在、null, undefined, false, 0, or NaN,或者 空字符串(没有trim) 或者 一个空的集合{{#}} 指令和 {{^}} 指令相反 */adult: function() {// this 指向的是整个数据本身return this.age >= 18;}};var tpl = document.querySelector("#demoTpl").innerHTML;document.write(Mustache.render(tpl, data));/*Mustache 在 parse(template) 的时候会对模板进行缓存,方便下次相同模板直接渲染数据而不用再解析,提升渲染性能。当页面模板较多的时候, 建议在页面最后或者定期清理模板所有缓存的模板引擎;释放一些一次性的模板引擎的缓存(释放资源,避免内存占用过多);然后一些动态的引擎等下一次渲染的时候,会自动缓存后续。 */Mustache.clearCache();

二、渲染列表 index 解决方案

1.在渲染前重新组装数据

var subdata = [{title: '数据1',desc: '数据描述1'}, {title: '数据2',desc: '数据描述2'}];for (var i = 0, sl = subdata.length; i < sl; i++) {var currItem = subdata[i];// 重新组装数据, 将 index 组装到列表项中Object.assign(currItem, {index: i});subdata[i] = currItem;}

2.通过一个全局变量

var template = "{{#subdata}}{{index}}{{/subdata}}";ar dataIndex = -1; // 全局变量缓存indexvar data = {subdata: [{title: '数据1',desc: '数据描述1'}, {title: '数据2',desc: '数据描述2'}],// 声明一个 index 函数来改变和获取全局缓存的 indexindex: function() {return ++dataIndex;}};

3.修改源代码

下面谈谈,我自己对于源代码的简单修改, 让源代码支持 列表 index。重点就是对于 Context 的修改。我直接贴代码,在代码的注释里,有变动提示。

a. 源代码 355 行, Context 构造函数

/** * Represents a rendering context by wrapping a view object and * maintaining a reference to the parent context. * Context (view, parentContext) --> Context (view, parentContext, itemIndex) * @param {Integer} itemIndex 列表项的 index */function Context (view, parentContext, itemIndex) {  this.view = view;  this.itemIndex = itemIndex; // 如果是渲染的列表的item, 带上 index  this.cache = { '.': this.view };  this.parent = parentContext;}

b. 修改 Context push 函数

/** * Creates a new context using the given view with this context as the parent. * push(view) --> push(view, itemIndex) * @param {Number} [itemIndex] [构造列表项 Context 时, 可以带上 item index, 以上引擎支持 渲染列表的 index] */ Context.prototype.push = function push (view, itemIndex) {   return new Context(view, this, itemIndex); };

c. 修改 Context lookup 函数

/**  * Returns the value of the given name in this context, traversing  * up the context hierarchy if the value is absent in this context's view.  * 如果是渲染的集合数据,并且 name 为 'index|$index',  *   则渲染Array index;如果数据本身有 name 字段,则以数据本身的name优先]  */ Context.prototype.lookup = function lookup (name) {    var cache = this.cache, itemIndex = this.itemIndex; // 获取列表项的 index    var value;    if (cache.hasOwnProperty(name)) {      value = cache[name];    }  else if((name === 'index' || name === '$index') && itemIndex >= 0) { // 渲染 列表 index      // 为了避免有时 index 冲突, 添加 $index      value = itemIndex;    } else {………

d. 修改 Writer --> renderSection 函数

if (isArray(value)) {  for (var j = 0, valueLength = value.length; j < valueLength; ++j) {    // 这里 context.push(value[j]) --> context.push(value[j], j) 传递列表项的 index    buffer += this.renderTokens(token[4], context.push(value[j], j), partials, originalTemplate);  }}
这样就基本改完了,然后就可以通过 {{index}}、{{$index}}的方式获取index了。

以上只是我自己的一些更改,如果觉得有什么不足或者有其它更好的解决方案,可以在评论中留言交流。

最后附上改版后(v 2.3.0) 的资源:mustache-index

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 当你烦的时候怎么办 面对刁蛮不讲理的老婆怎么办 老是想以前的事怎么办 被心机婊陷害了怎么办 分手了还被骚扰怎么办 苹果手机屏幕出现冷暖屏怎么办 我感觉媳妇不漂亮怎么办 90后赚不到钱怎么办 处对象感觉好累怎么办 谈朋友感觉好累怎么办 家庭条件不好娶老婆难办怎么办? 异地恋闹矛盾了怎么办 有人威胁要杀我全家怎么办 分手了借我的钱怎么办 脸打架打肿了怎么办 人家不加我qq好友怎么办 一个好友被删了怎么办 dnf脸黑怎么办还有办法 我想登别人微信怎么办 昌硕工资没到怎么办 昌硕离职不批怎么办 昌硕工资不到卡怎么办 上海人去苏州工作社保怎么办 娶个个脾气暴躁的媳妇怎么办 满脸的黑头痘痘怎么办 脚底磨起泡不敢走路怎么办 老婆老是找异性朋友怎么办 喜欢的人有对象怎么办 遇到了更喜欢的怎么办 8岁骨龄11岁怎么办啊 13岁初中生有思想不听话怎么办 交朋友找对象喜欢颜值高的怎么办 儿子找对象不听父母怎么办 缺爱怎么办的搞笑回答 对象说有人追她怎么办 说了一句话媳妇非常生气怎么办 柔顺后头发太臭怎么办 积分兑换手机被骗了怎么办 老板对你的上级不满怎么办 如果老板不给工资怎么办 手机号码被标记为其他公司怎么办?