将条纹样式添加到项目列表中

时间:2011-06-22 06:16:29

标签: knockout.js zebra-striping

使用KnockoutJS对列表进行条带化的最佳方法是什么?下面div上的类应该是偶数或奇数,取决于它在列表中的位置,并在添加或删除项目时更新。

<div class="Headlines loader" 
     data-bind="css: { loader: headlines().length == 0 }, 
                       template: { name: 'recentHeadlinesTemplate',
                                   foreach: beforeHeadlineAddition, 
                                   beforeRemove: function(elem) { $(elem).slideUp() },
                                   afterAdd: slideDown }">
</div>

<script type="text/html" id="recentHeadlinesTemplate">
    <div class="even">
        ${Title}
    </div>  
</script>

6 个答案:

答案 0 :(得分:57)

我发现了一个在使用foreach迭代时返回索引的函数,因此您可以以合理紧凑的方式应用偶数和奇数类,例如:

<tr data-bind="css: { 'even': ($index() % 2 == 0) }">

答案 1 :(得分:21)

KO论坛上有一个关于此问题的主题:https://groups.google.com/d/topic/knockoutjs/cJ2_2QaIJdA/discussion

我的解决方案是自定义绑定。它有几个变化,但基本上看起来像:

ko.bindingHandlers.stripe = {
    update: function(element, valueAccessor, allBindingsAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor()); //creates the dependency
        var allBindings = allBindingsAccessor();
        var even = allBindings.evenClass;
        var odd = allBindings.oddClass;

        //update odd rows
        $(element).children(":nth-child(odd)").addClass(odd).removeClass(even);
        //update even rows
        $(element).children(":nth-child(even)").addClass(even).removeClass(odd);;
    }
}

用作:

<ul data-bind="template: { name: 'itemsTmpl', foreach: items }, stripe: items, evenClass: 'light', oddClass: 'dark'"></ul>

此处的示例包含此绑定的3种变体:

http://jsfiddle.net/rniemeyer/HJ8zJ/

答案 2 :(得分:3)

一种简单的方法是添加一个计算的observable,为每个元素添加一个索引,例如

    self.logLines = ko.observable(logLinesInput);

    self.enhancedLogLines = ko.computed(function() {
        var res = [];
        $.each(self.logLines(), function(index, ll) { 
             res.push(new LogLine(index, ll)); 
        });
        return res;
    }, self);

在我的情况下,LogLine()创建一个带有索引字段的对象以及原始对象中的其他字段。

现在您可以轻松地在输出中添加斑马条纹:

            <tr data-bind="css: { odd: (index % 2 == 1), even: (index % 2 == 0) }">

答案 3 :(得分:2)

感谢有用的帖子。我想提一下,css可以很好地完成条带化,但是嵌入式的“如果&#39;只有在渲染了行之后才能起作用。因此,使用$ index或css奇数/偶数功能不会产生所需的结果。在不使用模板的情况下,我发现您可以在行周围包含KO逻辑,以便在计算行之前发生逻辑。

<tbody data-bind="foreach: viewModel.configuration().items()"">
    <!-- ko if: $data.part() != '' -->
    <tr>
            <td data-bind="text: $index"></td><td  data-bind="text: $data.part()"></td>
    </tr>
    <!-- /ko -->
</tbody>

答案 4 :(得分:0)

您可以使用模板中的{{if}}{{else}}条件语句来设置div的类。

此外,您还需要扩展View Model以包含一个返回当前项目索引的函数,该函数会告诉您它是奇数还是偶数。 (Something like this

答案 5 :(得分:0)

这是一个完整的例子:

<ul class="pickupPointHours" data-bind="foreach: Items">
 <li data-bind="css: { lineEven: ($index()%2 === 0), lineOdd: ($index()%2 === 1)}">
  <span class="pickupPointDay" data-bind="text: TextProperty"></span>
 </li>
</ul>