2013-12-13 2 views
5

В этом jsfiddle У меня есть простой пример того, что я хочу делать. Все работает нормально. Но кажется, что должен быть лучший способ создать эти массивы с помощью некоторых циклов или чего-то еще. Я пробовал весь день и не добился успеха. Может кто-нибудь сказать мне, еслиЛучший способ настроить наблюдаемый массив вычисляемых объектов в Knockoutjs

  1. это возможно
  2. , что вуду мне нужно выполнить для того, чтобы работать.

Вот код со скрипки.

Вид:

<table> 
<tbody> 
    <tr> 
     <td></td> 
     <!-- ko foreach: topvals --> 
     <td > 
      <input type="text" data-bind="value: val"/> 
     </td> 
     <!-- /ko --> 
    </tr> 
    <tr> 
     <td><input type="text" data-bind="value:sidevals()[0].val"/></td> 
     <!-- ko foreach: intersections()[0] --> 
     <td><span data-bind="text: val"></span></td> 
     <!-- /ko --> 
    </tr> 
    <tr> 
     <td ><input type="text" data-bind="value:sidevals()[1].val"/></td> 
     <!-- ko foreach: intersections()[1] --> 
     <td><span data-bind="text: val"></span></td> 
     <!-- /ko --> 
    </tr> 
</tbody> 
</table> 

ViewModel:

function ViewModel() { 

    this.topvals = ko.observableArray([ 
     { val: ko.observable(6) }, 
     { val: ko.observable(1) }, 
     { val: ko.observable(1) }, 
     { val: ko.observable(1) } 
    ]); 

    this.sidevals = ko.observableArray([ 
     { val: ko.observable(1) }, 
     { val: ko.observable(1) }, 
     { val: ko.observable(1) } 
    ]); 

    this.intersections = ko.observableArray([ 
     [ 
      { val: ko.computed(function() { return this.topvals()[0].val() * this.sidevals()[0].val(); }, this) }, 
      { val: ko.computed(function() { return this.topvals()[1].val() * this.sidevals()[0].val(); }, this) }, 
      { val: ko.computed(function() { return this.topvals()[2].val() * this.sidevals()[0].val(); }, this) }, 
      { val: ko.computed(function() { return this.topvals()[3].val() * this.sidevals()[0].val(); }, this) } 
     ], 
     [ 
      { val: ko.computed(function() { return this.topvals()[0].val() * this.sidevals()[1].val(); }, this) }, 
      { val: ko.computed(function() { return this.topvals()[1].val() * this.sidevals()[1].val(); }, this) }, 
      { val: ko.computed(function() { return this.topvals()[2].val() * this.sidevals()[1].val(); }, this) }, 
      { val: ko.computed(function() { return this.topvals()[3].val() * this.sidevals()[1].val(); }, this) } 
     ] 
    ]); 
} 

ko.applyBindings(new ViewModel()); 
+0

Было бы особенно полезно, если бы я мог абстрагироваться от «перекрестка», особенно потому, что есть умеренно сложное уравнение, которое должно быть выполнено с помощью topval, sideval и константы. Я еще не понял этого: -/ – jgonyer

+0

Обязательно добавьте KO в зависимости от jsfiddle-зависимостей .. здесь совсем не работает. – user2864740

ответ

3
  • Для создания topvals и sidevals массивы можно использовать ko.mapping.fromJS.
  • Для создания вычисленного intersections вы можете вернуть «массив массивов» с помощью функции ko.utils.arrayMap.

Вот окончательный код (и jsfiddle):

function ViewModel() { 
    var self = this; 

    var calculateIntersection = function(topval, sideval) { 
     return topval * sideval; 
    }; 

    var topvals = [{ val: 1 }, { val: 2 }, { val: 3 }]; 
    var sidevals = [{ val: 1 }, { val: 2 }, { val: 3 }]; 

    self.topvals = ko.mapping.fromJS(topvals); 
    self.sidevals = ko.mapping.fromJS(sidevals); 
    self.intersections = ko.computed(function() { 
     return ko.utils.arrayMap(self.sidevals(), function(sideval) { 
      return ko.utils.arrayMap(self.topvals(), function(topval) { 
       return calculateIntersection(topval.val(), sideval.val()); 
      }); 
     }); 
    }); 
} 

ko.applyBindings(new ViewModel()); 

А вот вид:

<table> 
    <tbody> 
     <tr> 
      <td></td> 
      <!-- ko foreach: topvals --> 
      <td > 
       <input type="text" data-bind="value: val"/> 
      </td> 
      <!-- /ko --> 
     </tr> 
     <!-- ko foreach: sidevals --> 
     <tr> 
      <td><input type="text" data-bind="value: val"/></td> 
      <!-- ko foreach: $root.intersections()[$index()] --> 
      <td><span data-bind="text: $data"></span></td> 
      <!-- /ko --> 
     </tr> 
     <!-- /ko --> 
    </tbody> 
</table> 
1

Этот простой вид модели уже делает это:

function ViewModel(vals1, vals2) { 
    this.topvals = ko.observableArray(mapToObservables(vals1)); 
    this.sidevals = ko.observableArray(mapToObservables(vals2)); 
    this.calc = function (val1, val2) { 
     return ko.unwrap(val1) * ko.unwrap(val2); 
    }; 
} 

ko.applyBindings(new ViewModel([6, 5, 4, 3], [1, 2, 3])); 

, где mapToObservables означает либо отображение плагин или функция, как этот:

function mapToObservables(vals) { 
    return ko.utils.arrayMap(vals, function (val) { 
     return { val: ko.observable(val) }; 
    }); 
}; 

и этот вид

<table> 
<tbody> 
    <tr> 
     <td></td> 
     <!-- ko foreach: topvals --> 
     <td><input type="text" data-bind="value: val"/></td> 
     <!-- /ko --> 
    </tr> 
    <!-- ko foreach: sidevals --> 
    <tr> 
     <td><input type="text" data-bind="value: val"/></td> 
     <!-- ko foreach: $root.topvals --> 
     <td><span data-bind="text: $root.calc(val, $parent.val)"></span></td> 
     <!-- /ko --> 
    </tr> 
    <!-- /ko --> 
</tbody> 
</table> 

См: http://jsfiddle.net/dt9kL/

Вариант будет использовать отдельный суб-модель для значений: http://jsfiddle.net/dt9kL/1/. Для инкапсуляции единственного значения это избыточное, но может быть полезно для более сложных структур.

Смежные вопросы