Templates 在Mustach中,如何获取当前节的索引
我正在使用和使用数据Templates 在Mustach中,如何获取当前节的索引,templates,mustache,Templates,Mustache,我正在使用和使用数据 { "names": [ {"name":"John"}, {"name":"Mary"} ] } 我的胡子模板是: {{#names}} {{name}} {{/names}} 我希望能够得到数组中当前数字的索引。比如: {{#names}} {{name}} is {{index}} {{/names}} 把它打印出来 John is 1 Mary is 2 有没有可能把这个和胡子连在一起?或者使用Handlebar或其他扩展?如果可以控制JSO
{ "names": [ {"name":"John"}, {"name":"Mary"} ] }
我的胡子模板是:
{{#names}}
{{name}}
{{/names}}
我希望能够得到数组中当前数字的索引。比如:
{{#names}}
{{name}} is {{index}}
{{/names}}
把它打印出来
John is 1
Mary is 2
有没有可能把这个和胡子连在一起?或者使用Handlebar或其他扩展?如果可以控制JSON字符串的输出,请尝试此操作
{ "names": [ {"name":"John", "index":"1"}, {"name":"Mary", "index":"2"} ] }
因此,在创建JSON字符串时,将索引添加为每个对象的另一个属性。在handlebar.js中,您可以通过一个helper函数来实现这一点。(事实上,这里提到的关于Handlebar的一个优点是,您可以使用helpers,而不必在调用模板之前重写对象 所以,你可以这样做:
var nameIndex = 0;
Handlebars.registerHelper('name_with_index', function() {
nameIndex++;
return this.name + " is " + nameIndex;
})
然后,您的模板可以是:
{{#names}}
<li>{{name_with_index}}</li>
{{/names}}
您可以得到以下输出:
<li>John is 1</li>
<li>Mary is 2</li>
约翰一岁了
var data = { "names": [ {"name":"John"}, {"name":"Mary"} ] };
var templateSource = "<ul>{{reset_index}}{{#names}}<li>{{name_with_index}}</li>{{/names}}</ul>";
var template = Handlebars.compile(templateSource);
var helpers = function() {
var nameIndex = 0;
Handlebars.registerHelper('name_with_index', function() {
nameIndex++;
return this.name + " is " + nameIndex;
});
Handlebars.registerHelper('reset_index', function() {
nameIndex = 0;
})
}();
var htmlResult= template(data);
$('#target').html(htmlResult);
var htmlResult2= template(data);
$('#target2').html(htmlResult2);
var data = {
names: [ {"name":"John"}, {"name":"Mary"} ],
index: function() {
return function(array, render) {
return data[array].indexOf(this);
}
}
};
var html = Mustache.render(template, data);
{{#array}}
{{@index}}
{{/array}}
var data={“name”:[{“name”:“John”},{“name”:“Mary”}]};
var templateSource=“{{reset_index}}{{{{names}}- {{name_with_index}}
{{/names}
”;
var template=handlebar.compile(templateSource);
var helpers=函数(){
var-nameIndex=0;
车把.注册表帮助器('name_,带索引',function()){
nameIndex++;
返回this.name+“is”+nameIndex;
});
把手.注册表帮助器('reset_index',function(){
nameIndex=0;
})
}();
var htmlResult=模板(数据);
$('#target').html(htmlResult);
var htmlResult2=模板(数据);
$('#target2').html(htmlResult2);
(这可以正确地渲染模板两次。)这里是伟大的助手:
// {{#each_with_index records}}
// <li class="legend_item{{index}}"><span></span>{{Name}}</li>
// {{/each_with_index}}
Handlebars.registerHelper("each_with_index", function(array, fn) {
var buffer = "";
for (var i = 0, j = array.length; i < j; i++) {
var item = array[i];
// stick an index property onto the item, starting with 1, may make configurable later
item.index = i+1;
// show the inside of the block
buffer += fn(item);
}
// return the finished buffer
return buffer;
});
/{{{{#每个_都有_索引记录}
//{{{Name}
//{{/each_with_index}
把手。注册表帮助器(“每个带索引的”功能(数组,fn){
var buffer=“”;
对于(var i=0,j=array.length;i
来源:这是我在JavaScript中的实现方式:
var idx = 0;
var data = {
"names": [
{"name":"John"},
{"name":"Mary"}
],
"idx": function() {
return idx++;
}
};
var html = Mustache.render(template, data);
您的模板:
{{#names}}
{{name}} is {{idx}}
{{/names}}
{{#names}}
{{name}} is {{index}}
{{/names}}
{{#names}}
{{name}} is {{#index}}names{{/index}}
{{/names}}
我的主要用例是在项目上放置一个“活动”类的能力。我把“equals”助手与“index_for_each”助手组合起来搞砸了,但这太复杂了 相反,我提出了以下基本的“活动”助手。它非常具体,但对于任何菜单/选择列表场景来说都是一个常见的用例: 用法:
<ul>
{{{active 2}}}
{{#each menuItem}}
<li class="{{{active}}}">{{this}}</li>
{{/each}}
</div>
您可以在对象列表上运行以下循环 此解决方案具有以下优点:
- 不更改模型数据
- 该索引可以多次访问
for( var i=0; i< the_list.length; i++) {
the_list[i].idx = (function(in_i){return in_i+1;})(i);
}
for(var i=0;i
说明:
for( var i=0; i< the_list.length; i++) {
the_list[i].idx = (function(in_i){return in_i+1;})(i);
}
使用函数而不是变量名,因此数据不会发生变化。闭包用于在循环中创建函数时返回“i”值,而不是在循环结束时返回“i”值。作为参考,此功能现在内置于与Mustache兼容的把手中 使用
{{@index}}
{{#names}}
{{name}} is {{@index}}
{{/names}}
约翰0岁
Mary是1只要您没有进入多个数组,就可以将索引存储在帮助器上,并在上下文更改时增加索引。我使用的是类似于以下内容的内容:
var data = {
foo: [{a: 'a', 'b': 'a'}, {'a':'b', 'b':'b'}],
i: function indexer() {
indexer.i = indexer.i || 0;
if (indexer.last !== this && indexer.last) {
indexer.i++;
}
indexer.last = this;
return String(indexer.i);
}
};
Mustache.render('{{#foo}}{{a}}{{i}}{{b}}{{i}}{{/foo}}', data);
更好的方法是使用一个函数,该函数使用
indexOf
获取索引:
var data = {
names: [ {"name":"John"}, {"name":"Mary"} ],
index: function() {
return data.names.indexOf(this);
}
};
var html = Mustache.render(template, data);
在模板中:
{{#names}}
{{name}} is {{idx}}
{{/names}}
{{#names}}
{{name}} is {{index}}
{{/names}}
{{#names}}
{{name}} is {{#index}}names{{/index}}
{{/names}}
缺点是此索引
函数具有数组硬编码的数据。名称
为了使其更具动态性,我们可以使用以下另一个函数:
var data = { "names": [ {"name":"John"}, {"name":"Mary"} ] };
var templateSource = "<ul>{{reset_index}}{{#names}}<li>{{name_with_index}}</li>{{/names}}</ul>";
var template = Handlebars.compile(templateSource);
var helpers = function() {
var nameIndex = 0;
Handlebars.registerHelper('name_with_index', function() {
nameIndex++;
return this.name + " is " + nameIndex;
});
Handlebars.registerHelper('reset_index', function() {
nameIndex = 0;
})
}();
var htmlResult= template(data);
$('#target').html(htmlResult);
var htmlResult2= template(data);
$('#target2').html(htmlResult2);
var data = {
names: [ {"name":"John"}, {"name":"Mary"} ],
index: function() {
return function(array, render) {
return data[array].indexOf(this);
}
}
};
var html = Mustache.render(template, data);
{{#array}}
{{@index}}
{{/array}}
模板中的用法:
{{#names}}
{{name}} is {{idx}}
{{/names}}
{{#names}}
{{name}} is {{index}}
{{/names}}
{{#names}}
{{name}} is {{#index}}names{{/index}}
{{/names}}
还有一个小缺点是,在本例中,必须将数组名传递给index函数names
,{{{index}}names{{/index}}
(在节点4.4.7,小胡子2.2.1中测试)
如果你想要一个干净的函数方式来实现它,不涉及全局变量或改变对象本身,使用这个函数
var withIds = function(list, propertyName, firstIndex) {
firstIndex |= 0;
return list.map( (item, idx) => {
var augmented = Object.create(item);
augmented[propertyName] = idx + firstIndex;
return augmented;
})
};
在组装视图时使用它
var view = {
peopleWithIds: withIds(people, 'id', 1) // add 'id' property to all people, starting at index 1
};
这种方法的好处在于,它创建了一组新的“viewmodel”对象,将旧对象集用作原型。您可以像读取person.firstName
一样读取person.id
。但是,此函数根本不会更改您的people对象,因此其他代码(可能依赖于不存在ID属性)不会受到影响
算法是O(N),非常好而且快速。推荐解决方案
我的建议是添加一个
索引
键
let data = { "names": [ {"name":"John"},
{"name":"Mary"} ] };
// Add an index manually
data = {
names: [
{ id: 0, name: "John" },
{ id: 1, name: "Mary" }
]
};
// Add an index with a loop
data = data.names
.map(function (name, i) {
name.id = i;
return name;
});
// Nested arrays with indices (parentId, childId)
data = {
names: [{
parentId: 0,
name: "John",
friends: [{
childId: 0,
name: "Mary"
}]
}]
};
其他建议的解决方案没有那么干净,并且存在许多问题,详情如下
建议的胡须索引解决方案的问题
@Index 小胡子不支持@Index IndexOf 此解决方案在O(n^2)时间内运行,因此没有最佳性能。此外,必须为每个列表手动创建索引
const data = {
list: ['a', 'b', 'c'],
listIndex: function () {
return data.list.indexOf(this);
}
};
Mustache.render('{{#list}}{{listIndex}}{{/list}}', data);
const data = {
list: ['a', 'b', 'c'],
listIndex: function () {
return (++window.listIndex || (window.listIndex = 0));
}
};
Mustache.render('{{#list}}{{listIndex}}{{/list}}', data);
全局变量
此解决方案在O(n)时间内运行,因此在这里性能更好,但也“污染了全局空间”(即,添加到窗口
对象的任何属性,在浏览器窗口关闭之前都不会被垃圾回收),并且必须为每个列表手动创建索引
const data = {
list: ['a', 'b', 'c'],
listIndex: function () {
return data.list.indexOf(this);
}
};
Mustache.render('{{#list}}{{listIndex}}{{/list}}', data);
const data = {
list: ['a', 'b', 'c'],
listIndex: function () {
return (++window.listIndex || (window.listIndex = 0));
}
};
Mustache.render('{{#list}}{{listIndex}}{{/list}}', data);
局部变量
此解决方案在O(n)时间内运行,不会“污染全局空间”,并且不需要手动进行cr