无法在 JSRender 循环中设置和访问动态变量
Not able to set and access a dynamic variable in a JSRender loop
我有一个循环,我只想在项目名称更改时显示 header。
所以我想设置一个变量 previousProject 并在 IF 语句中比较它。
我试过如下设置:
{{* window.previousProject=:project}}
如下所示,阅读它:
{{* if window.previousProject==:project}}
但我无法让它工作。
更新:
我想要完成的是:
HEADER 1 (This only prints on the first occurrence of HEADER 1)
ITEM 1.1
ITEM 1.2
ITEM 1.3
...
HEADER 2 (This only prints on the first occurrence of HEADER 2)
ITEM 2.1
ITEM 2.2
ITEM 2.3
...
所以 HEADER 实际上是 data.project。
第一次,当header未定义时,我需要打印一个开口div + header
每次检测到新的 header 时,我都需要打印结束 div 和开始 div + header
最后一次(迭代中的最后一行)我需要打印结束语 div
我不确定我是否正确理解了您的预期行为(例如,project
是您传递给 render(data)
的数据的变量 data.project
,
或者它是在模板外全局定义的 JavaScript 变量。但无论如何你上面有一些语法错误,包括 :project
.
这是一个您可以尝试的工作示例,它可能会对您有所帮助。
<script id="myTemplate" type="text/x-jsrender">
{{* window.previousProject=data.project;}}
{{* if (window.previousProject==data.project) { }}
A {{*:data.project}} {{:project}}
{{* } else { }}
B {{*:window.previousProject}}
{{* } }}
{{* window.previousProject="Other project"; }}
{{* if (window.previousProject==data.project) { }}
A {{*:data.project}} {{:project}}
{{* } else { }}
B {{*:window.previousProject}}
{{* } }}
</script>
<div id="result"></div>
<script>
var data = {project: "My project"};
$.views.settings.allowCode(true);
var html = $("#myTemplate").render(data);
$("#result").html(html);
</script>
更新
也就是说,我不确定您是否真的需要使用 allowCode(true)
。根据您对场景的额外解释,这里有几个备选方案:
如果你有这个数据
data = {projects: [
{project: "Header1", item: "Item 1.1"},
{project: "Header1", item: "Item 1.2"},
{project: "Header1", item: "Item 1.3"},
{project: "Header2", item: "Item 2.1"},
{project: "Header2", item: "Item 2.2"},
{project: "Header2", item: "Item 2.3"},
{project: "Header3", item: "Item 3.1"},
{project: "Header3", item: "Item 3.2"},
{project: "Header3", item: "Item 3.3"}
]};
您可以使用在模板渲染期间改变状态的方法,但不会暴露完整的 javascript 和 allowCode(true)
。而是传入具有 get/set 模式的 ~previousProject()
助手:
var _prevProject = ""; //initial state
var html = $("#myTemplate").render(data, {
prevProject: function(val) {
if (val===undefined) {
return _prevProject;
} else {
_prevProject=val;
return "";
}
}
});
使用以下模板:
<script id="myTemplate" type="text/x-jsrender">
{{for projects}}
{{if !~prevProject()}}
<div>{{:project}} {{:item}}
{{else ~prevProject()===project}}
{{:item}}
{{else}}
</div><div>{{:project}} {{:item}}
{{/if}}
{{:~prevProject(project)}}
{{/for}}
</div>
</script>
但实际上您根本不需要动态设置状态,而是可以直接访问数组项来测试 project
,如以下模板所示。 (不需要辅助函数):
<script id="myTemplate" type="text/x-jsrender">
{{for projects ~projects=projects}}
{{if #getIndex()===0}}
<div>{{:project}} {{:item}}
{{else}}
{{if ~projects[#getIndex()-1].project===project}}
{{:item}}
{{else}}
</div><div>{{:project}} {{:item}}
{{/if}}
{{/if}}
{{/for}}
</div>
</script>
如果可能,最好使用 JsRender 标准标签,而不是将 allowCode 设置为 true 并将 javascript 代码插入模板...
已添加:
上述解决方案工作正常,但模板不是很容易维护或理解,并且它不遵循或揭示输出的自然层次结构。所以另一种选择是使用 filter property:{{for filter=...}}
,如下所示:
助手
var html = $("#myTemplate").render(data, {
header: function(item, index, items) {
if (index===0 || item.project!==items[index-1].project) {
_prevProject=item.project;
return true;
}
},
items: function(item, index, items) {
return item.project===_prevProject;
}
});
模板:
<script id="myTemplate" type="text/x-jsrender">
{{for projects filter=~header ~projects=projects}}
<div>
{{:project}}
{{for ~projects filter=~items}}
{{:item}}
{{/for}}
</div>
{{/for}}
</script>
我有一个循环,我只想在项目名称更改时显示 header。
所以我想设置一个变量 previousProject 并在 IF 语句中比较它。
我试过如下设置:
{{* window.previousProject=:project}}
如下所示,阅读它:
{{* if window.previousProject==:project}}
但我无法让它工作。
更新:
我想要完成的是:
HEADER 1 (This only prints on the first occurrence of HEADER 1)
ITEM 1.1
ITEM 1.2
ITEM 1.3
...
HEADER 2 (This only prints on the first occurrence of HEADER 2)
ITEM 2.1
ITEM 2.2
ITEM 2.3
...
所以 HEADER 实际上是 data.project。
第一次,当header未定义时,我需要打印一个开口div + header
每次检测到新的 header 时,我都需要打印结束 div 和开始 div + header
最后一次(迭代中的最后一行)我需要打印结束语 div
我不确定我是否正确理解了您的预期行为(例如,project
是您传递给 render(data)
的数据的变量 data.project
,
或者它是在模板外全局定义的 JavaScript 变量。但无论如何你上面有一些语法错误,包括 :project
.
这是一个您可以尝试的工作示例,它可能会对您有所帮助。
<script id="myTemplate" type="text/x-jsrender">
{{* window.previousProject=data.project;}}
{{* if (window.previousProject==data.project) { }}
A {{*:data.project}} {{:project}}
{{* } else { }}
B {{*:window.previousProject}}
{{* } }}
{{* window.previousProject="Other project"; }}
{{* if (window.previousProject==data.project) { }}
A {{*:data.project}} {{:project}}
{{* } else { }}
B {{*:window.previousProject}}
{{* } }}
</script>
<div id="result"></div>
<script>
var data = {project: "My project"};
$.views.settings.allowCode(true);
var html = $("#myTemplate").render(data);
$("#result").html(html);
</script>
更新
也就是说,我不确定您是否真的需要使用 allowCode(true)
。根据您对场景的额外解释,这里有几个备选方案:
如果你有这个数据
data = {projects: [
{project: "Header1", item: "Item 1.1"},
{project: "Header1", item: "Item 1.2"},
{project: "Header1", item: "Item 1.3"},
{project: "Header2", item: "Item 2.1"},
{project: "Header2", item: "Item 2.2"},
{project: "Header2", item: "Item 2.3"},
{project: "Header3", item: "Item 3.1"},
{project: "Header3", item: "Item 3.2"},
{project: "Header3", item: "Item 3.3"}
]};
您可以使用在模板渲染期间改变状态的方法,但不会暴露完整的 javascript 和 allowCode(true)
。而是传入具有 get/set 模式的 ~previousProject()
助手:
var _prevProject = ""; //initial state
var html = $("#myTemplate").render(data, {
prevProject: function(val) {
if (val===undefined) {
return _prevProject;
} else {
_prevProject=val;
return "";
}
}
});
使用以下模板:
<script id="myTemplate" type="text/x-jsrender">
{{for projects}}
{{if !~prevProject()}}
<div>{{:project}} {{:item}}
{{else ~prevProject()===project}}
{{:item}}
{{else}}
</div><div>{{:project}} {{:item}}
{{/if}}
{{:~prevProject(project)}}
{{/for}}
</div>
</script>
但实际上您根本不需要动态设置状态,而是可以直接访问数组项来测试 project
,如以下模板所示。 (不需要辅助函数):
<script id="myTemplate" type="text/x-jsrender">
{{for projects ~projects=projects}}
{{if #getIndex()===0}}
<div>{{:project}} {{:item}}
{{else}}
{{if ~projects[#getIndex()-1].project===project}}
{{:item}}
{{else}}
</div><div>{{:project}} {{:item}}
{{/if}}
{{/if}}
{{/for}}
</div>
</script>
如果可能,最好使用 JsRender 标准标签,而不是将 allowCode 设置为 true 并将 javascript 代码插入模板...
已添加:
上述解决方案工作正常,但模板不是很容易维护或理解,并且它不遵循或揭示输出的自然层次结构。所以另一种选择是使用 filter property:{{for filter=...}}
,如下所示:
助手
var html = $("#myTemplate").render(data, {
header: function(item, index, items) {
if (index===0 || item.project!==items[index-1].project) {
_prevProject=item.project;
return true;
}
},
items: function(item, index, items) {
return item.project===_prevProject;
}
});
模板:
<script id="myTemplate" type="text/x-jsrender">
{{for projects filter=~header ~projects=projects}}
<div>
{{:project}}
{{for ~projects filter=~items}}
{{:item}}
{{/for}}
</div>
{{/for}}
</script>