2016-10-04 89 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>