我是Handlebars的新手,正在使用4.1.2版本。我正在尝试将一些用PHP编写的模板移到Handlebars。
我的数据源是一个JSON提要,其结构如下:
[
{
"regulations_label": "Europe",
"groups_label": "Group 1",
"filters_label: "FF1A"
},
{
"regulations_label": "Europe",
"groups_label": "Group 1",
"filters_label: "FF1B"
},
{
"regulations_label": "Europe",
"groups_label": "Group 2",
"filters_label: "FF2A"
},
{
"regulations_label": "Asia",
"groups_label": "Group 999",
"filters_label: "FF999A"
},
{
"regulations_label": "Asia",
"groups_label": "Group 999",
"filters_label: "FF999B"
},
{
"regulations_label": "Americas",
"groups_label": "Group 10000",
"filters_label: "FF10000A"
},
]
我的HTML模板(PHP版本)的输出如下:
达到此目的的方式-在输出过程中不复制任何regulations_label
或groups_label
-是使用条件逻辑来检查先前的数组值以查看如果已经改变,例如
// $data is the JSON above.
foreach ($data as $key => $d):
if ($data[$key-1]['groups_label'] !== $d['groups_label'])
echo $d['groups_label'];
endif;
endforeach;
上面的代码表示groups_label
仅在与先前值不同的情况下才呈现,即,它只能打印“ Group 1”一次,等等。
因此,在手把中,我想应用相同的原理。我已阅读Handlebars/Mustache - Is there a built in way to loop through the properties of an object?,并了解到有{{@index}}
和{{@key}}
。
我遇到的问题是我无法在这些条件上应用条件逻辑。例如,没有{{@index - 1}}
这样的东西。
我的设置方法如下:
<script id="regulations-template" type="text/x-handlebars-template">
{{#each myregs}}
- {{regulations_label}} <br>
-- {{groups_label}} <br>
---- {{filters_label}} <br>
{{/each}}
</script>
<script type="text/javascript">
var regsInfo = $('#regulations-template').html();
var template = Handlebars.compile(regsInfo);
var regsData = template({ myregs: // JSON data shown above });
$('#output').html(regsData);
</script>
<div id="output"></div>
内容呈现到#output
div,但是它会重复每个级别,例如
- Europe
-- Group 1
---- FF1A
- Europe
-- Group 1
---- FF1B
之所以会出现此问题,是因为我无法找到一种方法来查看先前的数组值是什么,并且无法执行条件逻辑。我该如何解决这个问题?
答案 0 :(得分:0)
我使用了一个递归函数(准备一个宽松的衬垫)来格式化数据,这种方式应该更容易显示。您可以将地图映射在孩子身上,然后使用标签进行打印:
const data = [
{ regulations_label: "Europe", groups_label: "Group 1", filters_label: "FF1A" },
{ regulations_label: "Europe", groups_label: "Group 1", filters_label: "FF1B" },
{ regulations_label: "Europe", groups_label: "Group 2", filters_label: "FF2A" },
{ regulations_label: "Asia", groups_label: "Group 999", filters_label: "FF999A" },
{ regulations_label: "Asia", groups_label: "Group 999", filters_label: "FF999B" },
{ regulations_label: "Americas", groups_label: "Group 10000", filters_label: "FF10000A" }
];
const r = (o, keys) => Object.entries(o.reduce((a, { [keys[0]]: l, ...r }) => ({ ...a, [l]: a[l] ? [...a[l], r] : [r] }), {})).map(([k, v]) => ({ label: k, children: keys.length === 2 ? v.map(o => o[keys[1]]) : r(v, keys.slice(1))}))
const myregs = r(data, ['regulations_label', 'groups_label', 'filters_label'])
const log = () => console.log(myregs)
var regsInfo = document.getElementById('regulations-template').innerHTML
var template = Handlebars.compile(regsInfo);
var regsData = template({myregs});
document.getElementById('output').innerHTML = regsData
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.1.2/handlebars.js"></script>
<script id="regulations-template" type="text/x-handlebars-template">
{{#each myregs}}
- {{this.label}} <br>
{{#each this.children}}
- - {{this.label}} <br>
{{#each this.children}}
- - - {{this}} <br>
{{/each}}
{{/each}}
{{/each}}
</script>
<button onclick="log()">Log data</button>
<div id="output"></div>
请注意,我删除了jQuery,只是因为我觉得不需要它,但可以随时将其添加回:)
答案 1 :(得分:0)
在纯车把解决方案中,您可以使用以下助手:
<script id="regulations-template" type="text/x-handlebars-template">
{{#each myregs}}
{{#ifPrevRegulation}} - {{regulations_label}} <br> {{/ifPrevRegulation}}
{{#ifPrevGroup}}-- {{groups_label}} <br>{{/ifPrevGroup}}
{{#ifPrevFilter}} ---- {{filters_label}} <br>{{/ifPrevFilter}}
{{setPrevContext}}
{{/each}}
</script>
哪里
var prevContext = null;
Handlebars.registerHelper('setPrevContext', function(){
prevContext = this;
});
Handlebars.registerHelper('ifPrevRegulation', function(options){
if(!(prevContext && this.regulations_label == prevContext.regulations_label)){
return options.fn(this);
}
});
Handlebars.registerHelper('ifPrevGroup', function(options){
if(!(prevContext && this.regulations_label == prevContext.regulations_label && this.groups_label== prevContext.groups_label)){
return options.fn(this);
}
});
Handlebars.registerHelper('ifPrevFilter', function(options){
if(!(prevContext && this.regulations_label == prevContext.regulations_label && this.groups_label== prevContext.groups_label && this.filters_label == prevContext.filters_label)){
return options.fn(this);
}
});