2013-12-13 10 views
5

このjsfiddleには、私が働きたいことの簡単な例があります。それはすべて正常に動作しています。しかし、いくつかのループなどでこれらの配列を作成するより良い方法があるように思えます。私は一日中努力してきており、成功していません。それは、私はそれを動作させるために実行するために必要なものブードゥー教 Knockoutjsで計算されたオブジェクトのobservableArrayを設定するためのより良い方法

  • 可能です

    1. 場合、誰かが私を伝えることができます。

    ここは、フィドルからのコードです。

    ビュー:

    <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

    jsfiddle依存関係にKOを手動で追加することを確認してください..ここではまったく動作しません。 – user2864740

    答えて

    3
    • あなたがko.mapping.fromJSを使用することができますtopvalssidevals配列を作成するには。
    • 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) }; 
        }); 
    }; 
    

    このビュー

    ​​

    参照:http://jsfiddle.net/dt9kL/1/http://jsfiddle.net/dt9kL/

    変異体は、値に対して別々のサブモデルを使用することであろう。単一の値をカプセル化する場合、これは過剰ですが、より複雑な構造の場合には便利です。

    関連する問題