haxxxton
haxxxton

Reputation: 6442

bind different Knockout JS templates inside foreach loop

I am trying to use KO templates to parse a JSON file (see here) into some pretty looking grid layouts.. (think similar to masonry/isotope layouts).. each template section will have different sized rectangles and squares inside it but the overall template conforms to a grid of 5 boxes wide by 3 boxes high (for example)

Given this what i have been trying to do is detect the template, then iterate through each item, if its a certain index in the iteration load either the single, double, or triple subtemplate..

my problem is that i cant seem to get it to check which key in the ViewTestProposal array im currently on..

below is my WIP code..

<div data-bind="template: {if: Template == 'basic2', visible: Template == 'basic2', foreach: ViewTestProposal}">
    <div data-bind="template: {if: ViewTestProposal[0], name: 'single'}"></div>
</div>
<script type="text/html" id="single">
    <div class="box single">
        <p data-bind="text: Artist, attr:{title: Artist}"></p>
    </div>
</script>

I have tried changing the if: ViewTestProposal[0] section to with: ViewTestProposal[0],if: ViewTestProposal() === 0 and if: ViewTestProposal == 0 to no avail.

Thanks in advance for any help you can provide

Upvotes: 0

Views: 2099

Answers (1)

Michael Best
Michael Best

Reputation: 16688

The template name parameter can be a function that returns the name based on the current item in the array (See note 4). With this you could access a property on each item that has the template name:

<div data-bind="template: {
        foreach: ViewTestProposal, 
        name: function(item) {return item.boxsize;}
    }"></div>

If you need to use the index of the item in the array, this is available starting with Knockout version 2.1 through the $index context property. Starting with version 2.2 (not yet released [1/Oct/2012], but release candidate version available), the name function can also access the context object. Then you could do something like this:

<div data-bind="template: {
        foreach: ViewTestProposal, 
        name: function(item, context) {
            switch(context.$index()) {
            case 0:
                return 'single';
            case 1:
                return 'double';
            // etc.
            }
        }
    }"></div>

Obviously, the function itself could be defined in your view model.

Upvotes: 4

Related Questions