Variables 无法在JSRender循环中设置和访问动态变量

Variables 无法在JSRender循环中设置和访问动态变量,variables,jsrender,Variables,Jsrender,我有一个循环,我只想在项目名称更改时显示标题 所以我想设置一个变量previousProject,并在IF语句中比较它 我尝试了如下设置: {{*window.previousProject=:project} 下面,请阅读: {{*if window.previousProject==:project}} 但我不能让它工作 更新: 我试图做到的是: HEADER 1 (This only prints on the first occurrence of HEADER 1) ITEM 1.1

我有一个循环,我只想在项目名称更改时显示标题

所以我想设置一个变量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
...
所以标题实际上是data.project

第一次,当标题未定义时,我需要打印期初div+标题

每次检测到新标题时,我都需要打印结束div和开始div+标题


最后一次(迭代的最后一行)我需要打印一个结束div

我不确定我是否正确理解了您的预期行为(例如,
project
变量
数据。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)
公开完整的javascript。而是使用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>
如果可能,最好使用JsRender标准标记,而不是将allowCode设置为true并将javascript代码插入模板中

增加:

上述解决方案工作正常,但模板不容易维护或理解,并且它不遵循或显示输出的自然层次结构。因此,另一种选择是使用:
{{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>

{{for projects filter=~header~projects=projects}}
{{:项目}
{{for~projects filter=~items}
{{:item}
{{/for}}
{{/for}}

这确实是我的意思;project是data.project。除了你的模板在开始制作
(window.previousProject==data.project)时设置
{{window.previousProject=data.project;}}}}
(window.previousProject==data.project)
始终为真,因此需要在最后设置。不幸的是,这不起作用。我将更新原始帖子,解释我试图实现的目标。这正是我正在寻找的解决方案。我昨天提出的解决方案是在项目对象旁边添加打开/关闭的布尔道具。非常感谢您提供的清晰详细信息iled解释。上面添加了另一种替代方法,使用{for}上的过滤器
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>