2013-12-13 5 views
5

einzurichten In diesem jsfiddle habe ich ein einfaches Beispiel für das, was ich tun möchte. Es funktioniert alles gut. Aber es scheint, als müsste es einen besseren Weg geben, diese Arrays mit einigen Schleifen oder etwas zu erstellen. Ich habe den ganzen Tag versucht und es ist mir nicht gelungen. Kann mir jemand sagen, obEine bessere Möglichkeit, ObservableArray von berechneten Objekten in Knockoutjs

  1. es möglich ist,
  2. was Voodoo ich ausführen müssen, um für sie zu arbeiten.

Hier ist der Code von der Geige.

Ausblick:

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

Ansichtsmodell:

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

Es wäre besonders hilfreich, wenn ich eine "Kreuzung" abstrahieren könnte, besonders da es eine moderat komplizierte Gleichung gibt, die mit der topval, sideval und einer Konstante gemacht werden muss. Ich habe das auch noch nicht herausgefunden: -/ – jgonyer

+0

Stellen Sie sicher, dass Sie KO den jsfiddle Abhängigkeiten manuell hinzufügen .. funktioniert hier überhaupt nicht. – user2864740

Antwort

3
  • Um die topvals und sidevals Arrays erstellen Sie ko.mapping.fromJS verwenden können.
  • Um den berechneten intersections zu erstellen, können Sie ein "Array von Arrays" mit der ko.utils.arrayMap-Funktion zurückgeben. Hier

ist der endgültige Code (und ein 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()); 

Und hier ist die Ansicht:

<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

Dieses einfache Ansicht Modell bereits tut es:

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

wobei mapToObservables entweder für das Mapping steht Plug-in oder eine Funktion wie diese:

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

und diese Ansicht

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

See: http://jsfiddle.net/dt9kL/

Eine Variante ein separates Teilmodell für die Werte zu verwenden wäre: http://jsfiddle.net/dt9kL/1/. Um einen einzelnen Wert zu kapseln, ist dies ein Overkill, aber es könnte für komplexere Strukturen nützlich sein.

Verwandte Themen