带有基于变量的过滤器的KO模板

时间:2014-01-13 20:25:37

标签: knockout.js

我有一个项目数组,我想根据该数组中的数据将它们分成多个部分。如果条件成功,我正在使用KO,但是我必须为我想要的每个部分重复部分标记和条件。我想将该部分转换为模板以避免重复,但我不知道如何使用变量等级在模板中包含if条件。有没有办法将变量传递给模板并在模板中引用该变量?

这是HTML:

<strong>Rank 1:</strong><br/>
<ul data-rank="1" data-bind="foreach: listItems">
    <!-- ko if: rank == 1 -->
    <li data-bind="text: name + ' (' + rank + ')'"></li>
    <!-- /ko -->
</ul>

<strong>Rank 2:</strong><br/>
<ul data-rank="2" data-bind="foreach: listItems">
    <!-- ko if: rank == 2 -->
    <li data-bind="text: name + ' (' + rank + ')'"></li>
    <!-- /ko -->
</ul>

<strong>Rank 3:</strong><br/>
<ul data-rank="3" data-bind="foreach: listItems">
    <!-- ko if: rank == 3 -->
    <li data-bind="text: name + ' (' + rank + ')'"></li>
    <!-- /ko -->
</ul>

JavaScript:

$(document).ready(function() {
    var viewModel = {};

    viewModel.listItems = ko.observableArray();
    viewModel.listItems.push({name: "A", rank: 1});
    viewModel.listItems.push({name: "B", rank: 1});
    viewModel.listItems.push({name: "C", rank: 2});
    viewModel.listItems.push({name: "D", rank: 2});
    viewModel.listItems.push({name: "E", rank: 1});
    viewModel.listItems.push({name: "F", rank: 3});
    viewModel.listItems.push({name: "G", rank: 2});

    ko.applyBindings(viewModel);
});

一个工作小提琴:
http://jsfiddle.net/RationalGeek/9eftr/

1 个答案:

答案 0 :(得分:1)

我会在viewmodel上创建一个过滤函数:

viewModel.filterByRank = function(rank) {
    return ko.utils.arrayFilter(viewModel.listItems(), function(item) {
        return item.rank == rank;
    });
}

然后在绑定中使用此函数:

<strong>Rank 1:</strong><br/>
<ul data-rank="1" 
    data-bind="template: { name: 'temp', foreach: filterByRank(1) }">
</ul>

<strong>Rank 2:</strong><br/>
<ul data-rank="2" 
    data-bind="template: { name: 'temp', foreach: filterByRank(2) }">
</ul>

<strong>Rank 3:</strong><br/>
<ul data-rank="3" 
    data-bind="template: { name: 'temp', foreach: filterByRank(3) }">
</ul>

<script id="temp" type="text/html">
    <li data-bind="text: name + ' (' + rank + ')'"></li>
</script>

演示JSFiddle

或者您可以将整个标记移动到模板并使用它:

<!-- ko template: { name: 'temp', data: { rank: 1, items: filterByRank(1) } } -->
<!-- /ko -->

<script id="temp" type="text/html">
    <strong>Rank <!-- ko: text: rank --><!-- /ko --></strong>
    <br/>
    <ul data-bind="foreach: items, attr: { 'data-rank': rank}">
        <li data-bind="text: name + ' (' + rank + ')'"></li>
    </ul>
</script>

演示JSFiddle