jsViews - 重新评估'如果' root属性更改时标记

时间:2015-05-07 10:30:29

标签: javascript jquery jsviews

我使用jsViews创建了一个表/网格。每行都有一个编辑按钮,单击该按钮可选择行并显示输入控件而不是文本值。

如果我使用data-link="visible{:#parent.parent.data.selectedIndex!==#index}"显示/隐藏输入,那么它可以正常工作。

但是,我尝试使用{^{if #parent.parent.data.selectedIndex===#index}}...{{else}}...{{/if}}显示/隐藏输入的不同方法,当selectedIndex更改数据对象时,这不起作用。

我也试过{^{if ~root.selectedIndex===#index}},但那也没有用。是否可以使用{{if}}执行此操作?我在第一个有效的方法上尝试这个的原因是为了避免渲染大量的选择框,这些选择框无论如何都会被隐藏。

我的数据对象如下所示:

app = {
    data: [...],

    selectedIndex: null,

    select: function select(index) {
        if (this.selectedIndex !== index) {
            $.observable(this).setProperty("selectedIndex", index);
        }
    }
};

我像这样链接模板:

$.templates("#myTemplate").link("#divHolder", app)
    .on("click", ".data .editButton", function() {
        app.select($.view(this).index);
    })
    .on("click", ".data .saveButton", function() {
        // save details
    })
    .on("click", ".transmittals .cancelButton", function() {
        // reset values

        app.select(null);
    });

我的模板是这样的:

<script id="myTemplate" type="text/x-jsrender">
    <table id="tblData" class="data">
        <thead>
            <tr>
                <th></th>
                <th>A</th>
                <th>B</th>
                <th>C</th>                    
            </tr>
        </thead>
        <tbody>
            {^{for data}}
            <tr class="item">
                <td>
                    {{if #parent.parent.data.selectedIndex===#index}}
            <span class="editItem">
                <button class="cancelButton">Cancel</button></span>
                    {{else}}
            <span class="viewItem">
                <button class="editButton">Edit</button></span>
                    {{/if}}                
                </td>
                <td>
                    {^{if #parent.parent.data.selectedIndex===#index}}
            <span class="editItem"><input type="text" data-link="B" /></span>
                    {{else}}
            <span class="viewItem" data-link="B"></span>
                    {{/if}}
                </td>
                <td>
                    {^{if #parent.parent.data.selectedIndex===#index}}
            <span class="editItem"><input type="text" data-link="C" /></span>
                    {{else}}
            <span class="viewItem" data-link="C"></span>
                    {{/if}}
                </td>
            </tr>
        {{/for}}
        </tbody>
    </table>
</script>

1 个答案:

答案 0 :(得分:1)

当您添加{{if}}块时,它是一个嵌套视图,因此按钮单击不会使您获得带索引的项目视图。您需要使用$.view(this).parent.index - 或更简单的$.view(this).getIndex() - 它会自动将嵌套视图(如果有的话)升级到项目视图并获取其索引。

app.select($.view(this).getIndex());

(见这里的讨论:https://github.com/BorisMoore/jsrender/issues/173#issuecomment-11058106

BTW这里是您的样本的修改形式,只是为了给您一些想法。它使用<button data-link="{on ~root.select #getIndex()}">Edit</button>来连接按钮上的click处理程序并直接调用select方法,并将索引传递给它:

<script id="myTemplate" type="text/x-jsrender">
<table id="tblData" class="data">
    <thead>
        ...
    </thead>
    <tbody>
    {^{for data}}
        <tr class="item">
        {^{if ~root.selectedIndex===#index}}
            <td><button class="cancelButton" data-link="{on ~root.select null}">Cancel</button></td>
            <td><input data-link="A" /></td>
            <td><input data-link="B" /></td>
        {{else}}
            <td><button class="editButton" data-link="{on ~root.select #getIndex()}">Edit</button></td>
            <td data-link="A"></td>
            <td data-link="B"></td>
        {{/if}}
        </tr>
    {{/for}}
    </tbody>
</table>
</script>

<div id="divHolder"></div>

<script>
var app = {
    data: [{A:"aa", B: "bb"},{A:"aa2", B: "bb2"}],
    selectedIndex: null,
    select: function(index) {
        if (this.selectedIndex !== index) {
            $.observable(this).setProperty("selectedIndex", index);
        }
    }
};

$.templates("#myTemplate").link("#divHolder", app);
</script>