4

我想从淘汰 observableArray 向页面添加选项列表。当要显示的项目数量超过可配置数量时,应显示“更多选项...”按钮(或链接)。按下此按钮应显示所有项目并将按钮文本更改为“更少选项”。为了使它更有趣:该按钮应该只在有超过 1 个项目被隐藏时才显示。

下面的代码有效(请参阅this fiddle),但没有更清洁和更通用的解决方案(例如使用自定义绑定)吗?

<ul data-bind="foreach: options">
    <li data-bind="visible: $root.showMore() || $index() < $root.showMoreCount() || $root.options().length <= $root.showMoreCount()+1, text: $data"></li>
</ul>
<a data-bind="visible: options().length-1 > showMoreCount(), text: showMore() ? 'Less options' : 'More options', click: function () { showMore(!showMore()) }"></a>
4

1 回答 1

7

您可以编写一个自定义的可观察函数来合并您的所有功能:

ko.showMoreArray = function(initial) {
    var observable = ko.observableArray(initial);

    //observables to change behaviour
    observable.limit = ko.observable(3).extend({numeric:true});
    observable.showAll = ko.observable(false);

    //function to toggle more/less
    observable.toggleShowAll = function() {
        observable.showAll(!observable.showAll());
    };

    //computed observable for filtered results
    observable.display = ko.computed(function() {
        if (observable.showAll()) { return observable(); }
        return observable().slice(0,observable.limit());
    }, observable);

    return observable;
};

这实际上只是包装了您已经编写的内容,但它是可重用的并且使您的 HTML 更加整洁:

<input data-bind="value: $root.orders.limit, valueUpdate: 'afterkeyup'" /><br/>

<ul data-bind="foreach: orders.display">
    <li data-bind="text: $data"></li>
</ul>

<a data-bind="text: orders.showAll() ? 'Less options' : 'More options', 
    click: orders.toggleShowAll" href="#"></a>

我在jsFiddle上放了一个工作版本。

在上面的示例中,您需要绑定到display原始数​​组上的属性,但否则它将表现为所有代码的“完整”数组(我认为这通常更有意义)。但是,如果您希望它在您的代码中表现为过滤后的(即最多 3 个项目)数组,那么您可以通过与此处演示的类似方式实现这一点

于 2013-06-06T12:43:25.013 回答