2013-04-15 94 views
2

我是Durandal和Knockout的新手,我碰到一個問題,我找不出如何解決。Durandal/Knockout嵌套下拉表

我有一張信用卡表的視圖。每行都有兩個名爲Dimension1Key和Dimension2Key的嵌套下拉列表,它們由GetDimensionMatrix ajax調用填充。

Creditlines foreach被填充到for循環中,其中兩個下拉列表被定義爲可觀察的 - 並且Dimension2的數據被計算爲ko.compute。

表格和下拉列表最初正確地填入了正確的值 - 但嵌套工作不正常。無論我更改哪個Dimension1下拉菜單,self的引用都是在表格中的最後一行 - 因此將相應Dimension1的Dimension2填充爲最後一行的選定值中的值。 如果Dimension1值再次發生變化,則計算的函數的引用將被打破。但是,如果我更改最後一行的Dimension1的值,則先前更改的行Dimension2的值將更改 - 就好像現在連接到最後一行的引用的值一樣。

我很確定問題在於視圖模型循環中的self - 以及它存在的上下文 - 但我無法理解解決方案。

任何幫助? :-)

檢視:

<section> 
    <h2 data-bind="html:displayName"></h2> 

    <table class="table"> 
     <tbody data-bind="foreach: creditCardLines"> 
      <tr> 
       <td class="date" data-bind="text: Date"></td> 
       <td class="date" data-bind="text: DocumentNo"></td> 
       <td data-bind="text: Description"></td> 
       <td><select data-bind="options: $parent.dimension1List, optionsText: 'DimensionValue', optionsValue: 'DimensionKey', value: Dimension1Key"></select></td> 
       <td><select data-bind="options: dimension2List, optionsText: 'DimensionValue', optionsValue: 'DimensionKey', value: Dimension2Key"></select> </td> 
       <td data-bind="text: Currency"></td> 
       <td data-bind="text: CurrencyAmount"></td> 
       <td data-bind="text: ExchangeRate"></td> 
       <td data-bind="text: AmountLCY"></td> 
       <td data-bind="text: Comment"></td> 
       <td data-bind="text: ApprovedEmployee"></td> 
       <td data-bind="text: Id"></td> 
      </tr> 
     </tbody> 
    </table> 
</section> 

視圖模型:

define(function (require) { 

var submit = function() { 
    this.displayName = 'Rejseafregning'; 

    this.creditCardLines = ko.observableArray(); 

    var me = this; 

    this.activate = function() { 
     return $.when(
       $.get('/submit/GetCreditCardLines'), 
       $.get('/submit/GetDimensionMatrix') 
       ) 
      .then(function (creditCardLines, dimension1List) { 
       me.dimension1List = dimension1List[0].Data; 

       for (var i = 0; i < creditCardLines[0].Data.length; i++) { 
        var self = creditCardLines[0].Data[i]; 

        self.Dimension1Key = ko.observable(creditCardLines[0].Data[i].Dimension1Key); 
        self.Dimension2Key = ko.observable(creditCardLines[0].Data[i].Dimension2Key); 


        self.dimension2List = ko.computed(function() { 
         for (var j = 0; j < me.dimension1List.length; j++) { 
          if (me.dimension1List[j].DimensionKey === self.Dimension1Key()) { 
           return me.dimension1List[j].DimensionNext; 
          } 
         } 
        }); 

        me.creditCardLines.push(self); 
       } 
      }); 
     }; 
    }; 
    return submit; 
}); 

回答

2

當創建ko.computed可以在控制時所計算的被評爲的this值的第二參數傳遞。

當您創建dimension2List計算,你想要通過你當前的self在作爲第二個參數,然後在該方法中使用this像:

  self.dimension2List = ko.computed(function() { 
       for (var j = 0; j < me.dimension1List.length; j++) { 
        if (me.dimension1List[j].DimensionKey === this.Dimension1Key()) { 
         return me.dimension1List[j].DimensionNext; 
        } 
       } 
      }, self); 

否則,self當computeds值被重新評估的結果是self被設置爲最後一個值(最後一行),這是基於閉包在JS中工作的方式。

使用computed的第二個參數可確保將該特定值用作上下文。

+0

非常感謝你 - 這是上下文 - 但不是我懷疑的那個:-) – martinrene