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

Knockoutjs: how to filter a foreach binding without using if

本文关键字:if 情况下 过滤 绑定 foreach Knockoutjs      更新时间:2023-09-26

有没有一种方法可以使用自定义绑定来实现下面的语句,以消除if绑定:

<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.jsforeach的答案中的Way2吗:但只有当比较成立时?

创建另一个计算或函数来进行过滤,并且可以迭代而不是迭代订单,怎么样?

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

我认为性能最好的选择是从两个不同的数据库中获取数据,并将它们放在同一个视图模型中。例如,在javascript中的视图模型中,首先获取客户。然后抢订单。为每个客户添加一个订单属性,并添加一个可观察订单数组。

您的视图模型供视图使用。因此,最好是获取数据,无论它是如何犯罪的,并使其为视图工作。正如你提到的,"如果"很可能是一个性能问题。此外,如果您在注释中建议在函数中使用foreach,那么当可观察数组发生变化时,它将不必要地循环项目。我更喜欢先把我的视图模型整理好,然后用户交互很快。

2美分:)