Knockout.js - foreach绑定-测试是否为最后一个元素

wribegjk  于 2022-11-10  发布在  其他
关注(0)|答案(4)|浏览(162)

我正在使用以下模板:

<div class="datatypeOptions" data-bind="if: $data.datatypeTemplate().allowOptions">
    <h3>Allowed responses</h3>

    <p data-bind="if: $data.datatypeTemplate().datatypeOptions().length == 0">There are no responses for this question, yet. <a href="#" data-bind="click: function(d, e){$root.addDatatypeOption($data.datatypeTemplate());}">Add one</a>
    <ul data-bind="foreach: $data.datatypeTemplate().datatypeOptions()">
        <li>
            <a href="#" data-bind="text: name, click: $root.selectedDatatypeOption, visible: $data !== $root.selectedDatatypeOption()"></a>
            <input data-bind="value: name, visibleAndSelect: $data === $root.selectedDatatypeOption(), event: { blur: $root.clearDatatypeOption }, executeOnEnter: { callback: function(){ $root.addDatatypeOption($parent.datatypeTemplate()); } }" />
            //I want to show this a tag only if $data is the last element in the array.
Problem here ===>  <a href="#" data-bind="if: $data == $parent.datatypeTemplate().datatypeOptions()[ $parent.datatypeTemplate().datatypeOptions().length - 1 ], click: function(d, e){$root.addDatatypeOption($data.datatypeTemplate());}"><img src='/static/img/icons/custom-task-wizard/black/plus_12x12.png' title='Add option'></a>
        </li>
    </ul>
</div>

我在控制台中收到此错误:

Uncaught Error: Unable to parse bindings.
Message: TypeError: Object [object Object] has no method 'datatypeTemplate';
Bindings value: if: $data == $parent.datatypeTemplate().datatypeOptions()[ $parent.datatypeTemplate().datatypeOptions().length - 1 ], click: function(d, e){$root.addDatatypeOption($data.datatypeTemplate());}

如果传递的元素是数组中的最后一个元素,我唯一的选择是向视图模型添加一个返回true/false的函数吗?

rta7y2nd

rta7y2nd1#

我已经简化了这个问题,但是这个jsFiddle演示了一个可能的解决方案。

“if”绑定:

<div data-bind="if: ($index() === ($parent.data().length - 1))">I'm the last element</div>

无容器“if”绑定:

<!-- ko if: ($index() === ($parent.data().length - 1)) -->
<div>I'm the last element again</div>
<!-- /ko -->

您可以在foreach系结中使用$index,以取得目前系结项目的索引。使用该索引来与父代的原始集合进行比较。
有关绑定上下文的更多信息,请参见HERE

puruo6ea

puruo6ea2#

我注意到有很多人请求对KO进行增强,以支持foreach绑定中的$length$last$array保留属性,尽管由于各种原因(通常是性能),它们还没有进入代码库。
如果有人对使用自定义绑定针对特定情况公开这些元素感兴趣,下面是一个公开$length变量以打印“漂亮”列表的简单示例。
您只需在通常使用foreach的任何地方使用forEachWithLength

ko.bindingHandlers.forEachWithLength = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, context)
    {         
        return ko.bindingHandlers.foreach.init(element, valueAccessor, allBindingsAccessor, viewModel, context);
    },
    update: function (element, valueAccessor, allBindingsAccessor, viewModel, context) 
    {         
        var array = ko.utils.unwrapObservable(valueAccessor());
        var extendedContext = context.extend({"$length" : array.length });
        ko.bindingHandlers.foreach.update(element, valueAccessor, allBindingsAccessor, viewModel, extendedContext);   
    }
};

示例用法:

<div data-bind="forEachWithLength: myArray">
    <span data-bind="text: $data"></span>
    <!-- ko if: ($index() < $length-2) -->, <!-- /ko -->
    <!-- ko if: ($index() === $length-2) --> and <!-- /ko -->
</div>

输入:["One", "Two", "Three", "Four"]
输出:One, Two, Three and Four

Fiddle
Further reading

bxpogfeg

bxpogfeg3#

如果您使用foreach绑定中的as选项,请转到**most-upvoted answer to this question
如果您
DOforeach绑定中使用as运算符,则该答案NOT**有效。
下面是这种情况下的解决方案

<div data-bind="foreach:{data: Items, as :'item'}">
    <div data-bind="if: ($index() === ($parent.Items().length - 1))">I'm the last element</div>
</div>

用你正在使用的可观察数组的名字替换$parent.data()的秘密。

  • 在我的例子中,它被命名为Items,所以我用$parent.Items()替换了$parent.data()
    注意此解决方案适用于所有情况,(
    是否在foreach中使用as选项 *)
xzlaal3s

xzlaal3s4#

请尝试以下操作:
1.使用$root而不是$parent
1.提前准备最后一项,并将该项作为附加参数传递给模板。
1.封装可观察的最后一个元素。

相关问题