Add striped styling to a list of items

前端 未结 6 971
执笔经年
执笔经年 2021-02-01 17:43

What would be the best way to stripe a list with KnockoutJS? The class on the div below should be even or odd depending where it is in the list, and update when adding or removi

相关标签:
6条回答
  • 2021-02-01 17:49

    here is a full example :

    <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>
    
    0 讨论(0)
  • 2021-02-01 17:50

    You could use the {{if}} and {{else}} conditional statements inside the template to set the class of the div.

    Also you will need to extend your View Model to include a function which returns the index of your current item, which would tell you whether it's odd or even. (Something like this)

    0 讨论(0)
  • 2021-02-01 17:53

    Thanks for the helpful posts. I wanted to mention that css can do a good job of striping but the embedded 'if' only seems to function after the row has been rendered. Therefore, using $index or the css odd/even capabilities don't yield the desired results. Without using a template I found that you can wrap the KO logic around the row so that the logic occurs before the row is counted.

    <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>
    
    0 讨论(0)
  • 2021-02-01 18:05

    One easy way to do this is to add a computed observable that adds an index to each element, e.g.

        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);
    

    In my case LogLine() creates an object with an index field and the other fields that were in the original object.

    Now you can easily add zebra stripes to your output:

                <tr data-bind="css: { odd: (index % 2 == 1), even: (index % 2 == 0) }">
    
    0 讨论(0)
  • 2021-02-01 18:09

    There was a topic for this on the KO forums a while back here: https://groups.google.com/d/topic/knockoutjs/cJ2_2QaIJdA/discussion

    The solution that I had was a custom binding. There were a couple variations on it, but it basically would look like:

    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);;
        }
    }
    

    and be used like:

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

    Sample here with 3 variations of this binding:

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

    0 讨论(0)
  • 2021-02-01 18:10

    I've found a function that returns an index when iterating with foreach, so you can apply even and odd classes in a reasonably compact way, for example:

    <tr data-bind="css: { 'even': ($index() % 2 == 0) }">
    
    0 讨论(0)
提交回复
热议问题