2017-02-27 124 views
0

我對knockout.js有點新奇,而且我在繞過可觀測數組的某些操作的頭部時遇到了麻煩。這裏是我的代碼的樣子:Knockout.js可觀察陣列操作

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

    減少功能很容易,因爲各個建築物視圖模型不需要知道任何外部因素來作出決定;它可以是基於其可觀察位置的直接計算。增加功能比較棘手,因爲它取決於集合中所有其他建築物的狀態。

    這裏有一個選項可以避免子類必須知道父類。在每個建築物放置一個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