2016-10-04 91 views
0

我有下面的代码在我的Razor视图来填充单选按钮,应用过滤器上的淘汰赛减少功能

<!-- ko foreach: { data: ko.unwrap(cars).reduce(function (res, v, i) { res[i%2].push(v); return res; }, [[],[]]), as: 'cars' } --> 
    <div data-bind="foreach: cars"> 
     <label class="car"> 
     <div> 
      <input type="radio" name="Carinfo.Name" data-bind="checked: $root.carId, checkedValue: Id, value: Id"><span data-bind="text: model"></span          
     </div> 
      </label> 
    </div> 
<!-- /ko --> 
  1. 试图了解减少功能在这里做 ko.unwrap(汽车)。降低(功能(RES,v,I){RES [则i%2] .push(v);返回水库;}
  2. 我可以过滤汽车观察的阵列(像v.Make == '本田'),内部减少的功能和返回过滤车到DOM来填充单选按钮
+0

这种减少将奇数偶数元素的原始列表划分为两个数组。它看起来像这个转换不符合以下foreind bindind。 – TSV

回答

0

首先,您要从视图中移除所有这些逻辑并将其移至viewModel。
这会给你

  1. 正确的IntelliSense(自动完成,徘徊功能给他们,所有这些IDE善良信息)。
  2. 可读性:您查看只会看起来像:

    <!-- ko foreach: { data: filteredCars -->

  3. 可测性。您将能够在该视图模型属性上编写单元测试。测试视图特别困难。现在

答案

试图了解减少功能在这里做 ko.unwrap(汽车)。降低(功能(RES,V,I){资源[我%2] .push(v);返回 水库;}

ko.unwrap是取对对象的实际值的函数,无论它是否observabl是否。例如:

console.log(ko.unwrap(ko.observableArray([1, 2, 3]))); 
 
console.log(ko.unwrap([1, 2, 3]));
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

array reduce运行针对阵列的回调,并降低的累加器内的所有值。为了理解这个例子是干什么的,让我们上一个简单的例子运行它:

var cars = ["honda", "renault", "ford", "toyota", "volkswagen", "chevrolet", "volvo"]; 
 

 
var splitted = cars.reduce(function (res, v, i) { 
 
    res[i%2].push(v); return res; 
 
}, [[],[]]); 
 

 
console.log(splitted);

它基本上是分裂的车阵成两个阵列。第一排汽车有索引,第二排有奇数索引。

我可以过滤汽车观察到的阵列(如诉让== '本田'),里面 减少功能和返回过滤车到DOM来填充 单选按钮

是,您可以:再次,一个简单的小提琴:

// let's say this observable comes from another VM 
 
var cars = ko.observableArray([{ 
 
    maker: "honda", 
 
    country: "japan" 
 
}, { 
 
    maker: "renault", 
 
    country: "france" 
 
}, { 
 
    maker: "ford", 
 
    country: "us" 
 
}, { 
 
    maker: "toyota", 
 
    country: "japan" 
 
}, { 
 
    maker: "volkswagen", 
 
    country: "germany" 
 
}, { 
 
    maker: "chevrolet", 
 
    country: "us" 
 
}, { 
 
    make: "volvo", 
 
    country: "sweden" 
 
}]); 
 

 
var viewModel = function() { 
 
    this.japaneseCars = ko.computed(function() { 
 
    return ko.unwrap(cars).reduce(function(result, v, i) { 
 
     if (v.country === "japan") { 
 
     result.push(v.maker); 
 
     } 
 
     return result; 
 
    }, []); 
 
    }, this); 
 
}; 
 

 
var vm = new viewModel(); 
 
ko.applyBindings(vm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 

 
<div data-bind="foreach: japaneseCars"> 
 
    <input type="radio" name="cars" data-bind="attr: { value: $data }"> 
 
    <span data-bind=" text: $data " /> 
 
    <br /> 
 
</div>