admin管理员组

文章数量:1325440

In Knockout JS, is it possible to do a foreach that increments by 2? Something similar to:

for (var i = 0; i < array.length; i += 2) {
    // Do stuff
}

The reason I'd like to do this is because the data that I need to loop through is an array rather than an object. Example:

viewModel = function () {
    this.facets = ["Sample", 100, "Sample 2", 200];
}

But the data needs to be displayed like this:

<ul data-bind="foreach: facets"> <!-- Can this foreach be incremented by 2? -->
    <li>$data[$index]: $data[$index + 1]</li>
</ul>

Any help would be greatly appreciated.

In Knockout JS, is it possible to do a foreach that increments by 2? Something similar to:

for (var i = 0; i < array.length; i += 2) {
    // Do stuff
}

The reason I'd like to do this is because the data that I need to loop through is an array rather than an object. Example:

viewModel = function () {
    this.facets = ["Sample", 100, "Sample 2", 200];
}

But the data needs to be displayed like this:

<ul data-bind="foreach: facets"> <!-- Can this foreach be incremented by 2? -->
    <li>$data[$index]: $data[$index + 1]</li>
</ul>

Any help would be greatly appreciated.

Share Improve this question edited Jan 28, 2013 at 19:11 Ryan asked Jan 28, 2013 at 19:00 RyanRyan 1,39514 silver badges23 bronze badges 4
  • 1 Where is knockout here? what are you asking? – gdoron Commented Jan 28, 2013 at 19:02
  • Your example loop will do precisely that. Where is the problem? – Evan Davis Commented Jan 28, 2013 at 19:03
  • It is always a good idea to keep the template logic free. You should better prepare a navigable data structure beforehand and keep the templates free from such implementation details. – bikeshedder Commented Jan 28, 2013 at 19:16
  • This is a simplified example. This data is actually ing back from an $.ajax call, and I have no control over how the data is formatted. – Ryan Commented Jan 28, 2013 at 19:21
Add a ment  | 

4 Answers 4

Reset to default 5

You could write a custom binding handler for this but I would rather keep the templates free from such ugly details.

I would remend writing a ko.puted:

function Model() {
    this.data = ko.observableArray(["Sample", 100, "Sample 2", 200])
    this.items = ko.puted(function() {
        var value = [];
        var data = this.data();
        for (var i=0; i<data.length; i+=2) {
            value.push({ key: data[i], value: data[i+1]);
        }
        return value;
    }, this);
}

var model = new Model();

Now you can iterate over the items in your template and access key and value. Updating the original data array will automatically rebuild the items puted observable.

The template code would look like:

<ul data-bind="foreach: items">
    <li><span data-bind="text: key"></span>: <span data-bind="text: value"></span></li>
</ul>

My Repeat binding (https://github./mbest/knockout-repeat) allows you to specify a step option.

<ul>
    <li data-bind="repeat: {foreach: facets, step: 2}"
        data-repeat-bind="text: facets[$index] + ': ' + facets[$index+1]">
    </li>
</ul>

This is probably what you're looking for:

for (var i = 0; i < array.length; i += 2) {
    var sample = array[i];
    var number = array[i+1];
    var display = "<li>" + sample + ": " + number + "</li>" // display this
}

Looks like you already have it, though, so I'm not sure what the issue is...

You can use a function to create the structure you need to bind to:

 self.arrayFunc = function() {
    var result = [];

    for (var i = 0, length = array.length; i += 2) {
        result.push({first: array[i], second: [i + 1]};
    }

};

本文标签: javascriptKnockout JS foreach that increments by 2Stack Overflow