2017-02-27 18 views
0

私はknockout.jsに若干の変更がありました。私のコードは次のようになります。Knockout.js Observable Array Operations

var Building = function() { 
    var self = this; 
    self.nLocation = ko.observable(); 
    self.nBuilding = ko.observable(); 
    ... 
    self.increaseLocNum = function() { 
     self.nLocation(self.nLocation + 1); 
    }; 
} 
var Quote = function() { 
    var self = this; 
    var nQuoteID = ko.observable(); 
    ... 
    self.buildings = ko.observableArray([]); 
    self.addBuilding = function(){ 
     ... 
     // Build new building with next loc/building number 
     buildings.push(); 
    } 
    ... 
} 
ko.applyBindings(new Quote()); 

本質的に私はそれに複数の建物を持つことができる見積もりを持っています。各建物は、タブコントロール上の別のタブにバインドされています。これらのタブには、位置番号を増減する+/-ボタンがある「位置情報」フィールドがあります。

私は建物が最も高い位置番号で唯一の建物であれば、例えば(+/-ボタンを有効に設定するバインディング[有効にする]を使用する必要がありますここでは簡単なルールのいくつかの例は次のとおりです。

  • 建物場合
  • 場所の数が増加することができない最高の場所にのみ建物である場合に建物が位置に1
  • 場所の数が増加することはできませんされている場合数を減少させることができない場所1つの建物しかありません

ロジックはかなりストレートですが、このロジックがノックアウトのベストプラクティスに従うためにはどこに行かなくてはなりませんか?

答えて

1

個々のビルディングビューモデルが決定を行うための外部要因について知る必要がないため、減少関数は簡単です。観測可能な位置に基づいて簡単に計算することができます。増加関数は、コレクション内の他のすべての建物の状態に依存するため、扱いにくいです。

ここでは、子クラスが親クラスについて知る必要がないようにするオプションがあります。各建物にcanIncreaseオブザーバブルを配置しますが、親ビューモデルは実際の増減を処理して、すべての子をループして位置が変更されるたびに観測値を更新できるようにします。

var Building = function(location) { 
 
    var self = this; 
 
    self.nLocation = ko.observable(location); 
 
    self.nBuilding = ko.observable("-Building Name Here-"); 
 
    
 
    self.canIncrease = ko.observable(); //set by parent 
 
    self.canDecrease = ko.computed(function(){ 
 
    //Location number can't be decreased if the building is at location 1 
 
    return self.nLocation() > 1; 
 
    }); 
 
} 
 

 
var Quote = function() { 
 
    var self = this; 
 
    var nQuoteID = ko.observable(); 
 

 
    self.buildings = ko.observableArray([new Building(1)]); 
 

 
    self.addBuilding = function() { 
 
    // Build new building with next loc/building number 
 
    self.buildings.push(new Building(self.highestLocation() + 1)); 
 
    self.enableChildren(); 
 
    } 
 
    
 
    self.highestLocation = ko.computed(function(){ 
 
    var highest=0; 
 
    $.each(self.buildings(), function(key,value){ if(value.nLocation() > highest) highest = value.nLocation(); }); 
 
    return highest; 
 
    }); 
 
    
 
    self.increaseLocNum = function(building) { 
 
    building.nLocation(building.nLocation() + 1); 
 
    self.enableChildren(); 
 
    }; 
 
    self.decreaseLocNum = function(building) { 
 
    building.nLocation(building.nLocation() - 1); 
 
    self.enableChildren(); 
 
    }; 
 
    
 
    self.enableChildren = function(){ 
 
    //Location number can't be increased if the building is the only building on the highest location 
 
    //Location number can't be increased if there is only one building 
 
    $.each(self.buildings(), function(key, building){ 
 
     if(building.nLocation() === self.highestLocation() || self.buildings().length === 1){ 
 
      building.canIncrease(false); 
 
     }else{ 
 
      building.canIncrease(true); 
 
     } 
 
    }); 
 
    } 
 
} 
 

 
ko.applyBindings(new Quote());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 

 
<input type="button" data-bind="click: addBuilding" value="Add Building" /> 
 
<span style="margin-left: 8px;">Total Buildings: <label data-bind="text: buildings().length" /></span> 
 
<span style="margin-left: 8px;">Highest Location: <label data-bind="text: highestLocation" /></span> 
 
<br/> 
 
<table> 
 
    <thead> 
 
    <tr> 
 
     <th></th> 
 
     <th>Location</th> 
 
     <th>Building Name</th> 
 
    </tr> 
 
    </thead> 
 
    <tbody data-bind="foreach: buildings"> 
 
    <tr style="border: 1px solid blue;"> 
 
     <td> 
 
     <input type="button" data-bind="enable: canDecrease, click: $parent.decreaseLocNum" value="-" /> 
 
     <input type="button" data-bind="enable: canIncrease, click: $parent.increaseLocNum" value="+" /> 
 
     </td> 
 
     <td> 
 
     <span data-bind="text: nLocation"></span> 
 
     </td> 
 
     <td> 
 
     <span data-bind="text: nBuilding"></span> 
 
     </td> 
 
    </tr> 
 
    </tbody> 
 
</table>

+0

私は私がしなければならないだろうと疑わが、いくつかの安心を持って常にいい、ノックアウトして新しいものだけで何! – user3060454