Knockoutjs:如何在不使用if的情况下过滤foreach绑定

时间:2012-04-01 20:59:32

标签: javascript knockout.js

有没有办法使用自定义绑定实现下面的语句,以消除if-binding:

<div data-bind="foreach: $root.customersVM.customers">
    @Html.Partial("_Customer")
    <div data-bind="foreach: $root.ordersVM.orders">
        <!-- ko if: customer() == $parent.id() -->
        @Html.Partial("_Order")
        <!-- /ko -->
    </div>
</div>

或者换一种说法:在Knockout.js foreach: but only when comparison is true的答案中有人知道 Way 2 吗?

2 个答案:

答案 0 :(得分:10)

如何创建另一个执行过滤的计算机或函数,并且可以迭代而不是迭代订单?

HTML

<div data-bind="with: filteredCustomers('smith')">
    <span data-bind="text: name"></span>
</div>

<div data-bind="foreach: customers">
    <span data-bind="text: name"></span>
</div>

<div data-bind="foreach: filteredOrders(4)">
    <span data-bind="text: id"></span>
</div>

<div data-bind="foreach: orders">
    <span data-bind="text: id"></span>
</div>

<button data-bind="click: function() {customers.push({name:'Smith'});}">Add customer</button>
<button data-bind="click: function() {orders.push({id:4});}">Add order</button>

使用Javascript:

var vm = {
    customers: ko.observableArray([
        {name: 'Smith'}, {name: 'Williams'}, {name: 'Brown'}, {name: 'Miller'}
    ]),
    orders: ko.observableArray([
        {id: 1}, {id: 2}, {id: 3}, {id: 4}, {id: 4}
    ])
};

// return first hit (unique ID)
vm.filteredCustomers = function(name) {
   return ko.utils.arrayFirst(this.customers(), function(customer) {
      return (customer.name.toLowerCase() === name.toLowerCase());
   });
};

// return all hits
vm.filteredOrders = function(id) {
   return ko.utils.arrayFilter(this.orders(), function(order) {
      return (order.id === id);
   });
};

ko.applyBindings(vm);

答案 1 :(得分:1)

我认为你在性能上最好的选择是从两个不同的数据库中获取数据并将它们放在同一个视图模型中。例如,在javascript中的viewmodel中,首先抓住客户。然后抓住订单。向每个客户添加一个订单属性,并向其添加一个observablearray订单。

您的viewmodel供视图使用。所以最好采取数据,但它会犯罪,并使其适用于视图。如你所述,“if”可能是一个性能问题。此外,如果您在注释中使用foreach函数,则在可观察数组发生更改时,它会不必要地循环遍历项目。我更喜欢先按顺序获取我的viewmodel,然后用户交互很快。

2美分:)