在击倒减少功能上应用过滤器

时间:2016-10-04 23:21:56

标签: asp.net-mvc knockout.js

我在剃刀视图中有以下代码来填充单选按钮,

 <!-- 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. 试图了解reduce功能在这里做了什么 ko.unwrap(cars).reduce(function(res,v,i){res [i%2] .push(v); return res;}
  2. 我可以过滤汽车可观察阵列(例如v.Make ==&#39;本田&#39;),内部减少功能并将过滤后的汽车返回到DOM以填充单选按钮

1 个答案:

答案 0 :(得分:0)

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

  1. 正确的智能感知(自动完成,悬停功能提供有关它们和所有这些IDE优点的信息)。
  2. 可读性:你看起来就像这样:

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

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

  4. 现在您的回答

      

    尝试了解reduce函数在这里做了什么   ko.unwrap(cars).reduce(function(res,v,i){res [i%2] .push(v); return   水库; }

    ko.unwrap 是一个获取on对象实际值的函数,无论它是否可观察。例如:

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

    array reduce对数组运行回调,并减少累加器内的所有值。要了解此示例的作用,请在一个更简单的示例中运行它:

    &#13;
    &#13;
    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);
    &#13;
    &#13;
    &#13;

    它基本上将你的汽车阵列分成两个阵列。汽车具有偶数索引的第一个阵列,第二个具有奇数索引的阵列。

      

    我可以过滤汽车可观察阵列(如v.Make ==&#39; Honda&#39;),里面   减少功能并将过滤后的汽车返回到DOM来填充   单选按钮

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

    &#13;
    &#13;
    // 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);
    &#13;
    <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>
    &#13;
    &#13;
    &#13;