2013-06-03 41 views
0

我試圖做一些ASP.NET MVC 4應用程序的一些增強,使瀏覽器中大量使用knockout.js和MVVM模式。我正在採取淘汰賽,我非常喜歡它,但是我設法造成了意外的錯誤。錶行被刪除,由於淘汰賽代碼

我有一個表,我正在使用數據綁定屬性中的foreach外觀,該屬性通過一個挖空視圖模型循環並創建行。

在viewmodel中,我添加了一些更多的屬性來支持新的頁腳行,這些頁腳行總計了表中的數字列。

不幸的是,我在viewmodel中添加的屬性導致一個行在我回發給控制器時被刪除。我懷疑我用錯敲除構建添加這些總計...

...這是視圖模型內...

self.BudgetTotal = ko.computed(function() { 
    var total = 0; 
    //The problem is this loop! It's messing with the Phases observable array and it's all magic behind the scenes and I can't see what's going wrong 
    for (i = 0; i < self.Phases().length; i++) 
     total = parseFloat(total) + parseFloat(self.Phases()[i].Total()); 
    return format_number(total, 2); 
}); 

這是表:

<table class="table table-bordered table-compact"> 
       <thead> 
        <tr> 
         <th></th> 
         <th>Phase</th> 
         <th>Name</th> 
         <th>Phase Manager</th> 
         <th>Labor</th> 
         <th>Expense</th> 
         <th>Subs</th> 
         <th>Total</th> 
        </tr> 
       </thead> 
       <tbody data-bind="template: {foreach: Phases.sort(function (l, r) { return l.Code() > r.Code() ? 1 : -1 }) }"> 
        <tr> 
         <td><input type="checkbox" data-bind="checked: IsSelected, click:SelectionChanged"/></td> 
         <td class="phasecode" data-bind="text: Code"></td> 
         <td><input type="text" data-bind="value: Name, visible: IsAdditional" class="input-small phaseName" maxlength = "35"/><span data-bind="text: Name, visible: !IsAdditional()"></span></td> 
         <td><input type="hidden" id="CompanyCode" data-bind="value: Company().Code" /><input type="text" class="PhaseManagerTypeahead phaseManager" data-bind="value: PhaseManager().CodeName, enable: IsSelected" autocomplete="off"/></td> 
         <td> 
          <nobr><input class="span1" id="inputIcon" type="text" data-bind="value: Labor, enable: IsSelected" style="text-align:right" onblur="checkDecimal(this)" maxlength = "20"/></nobr> 
         </td> 
         <td> 
          <nobr><input class="span1" id="inputIcon" type="text" data-bind="value: Expenses, enable: IsSelected" style="text-align:right" onblur="checkDecimal(this)" maxlength = "20"/></nobr> 
         </td> 
         <td> 
          <nobr><input class="span1" id="inputIcon" type="text" data-bind="value: Subcontractor, enable: IsSelected" style="text-align:right" onblur="checkDecimal(this)" maxlength = "20"/></nobr> 
         </td> 
         <td data-bind="text: Total" style="min-width:80px; text-align:right"></td> 
        </tr>            
       </tbody> 
       <tfoot class="hideFromPrinter"> 
        <tr> 
         <td colspan="8"><a href="javascript:void(0);" data-bind='click: viewModel.addAdditionalPhase'>Add Additional Phase...</a></td> 
        </tr> 
       </tfoot> 
      </table> 

我刪除了顯示總計的頁腳行,但發現它與該錯誤無關。如果我註釋掉上面的敲除代碼,該錯誤消失。當我取消註釋時,錯誤返回。

解決方法是使用效用函數arrayForEach遍歷observable數組。

self.BudgetTotal = ko.computed(function() { 
var total = 0; 
ko.utils.arrayForEach(self.Phases, function (item) { 
    var value = parseFloat(item.Total()); 
    if(!isNaN(value)) 
     total += value; 
    } 
); 
return total.toFixed(2); 
}); 

回答

0

使用擊倒arrayForEach圍繞這一問題的工作:

self.BudgetTotal = ko.computed(function() { 
    var total = 0; 
    ko.utils.arrayForEach(self.Phases, function (item) { 
     var value = parseFloat(item.Total()); 
     if(!isNaN(value)) 
      total += value; 
    ); 
    return total.toFixed(2); 
}); 

谷歌搜索使我這個建議使用arrayForEach的塊。

http://www.knockmeout.net/2011/04/utility-functions-in-knockoutjs.html

1

您的綁定是問題。您說您綁定了模板,但沒有指定模板名稱。只要綁定使用的foreach,它會工作:

<tbody data-bind="foreach: Phases"> 
    <tr>...</tr> 
    </tbody> 

或指定模板名稱:

<tbody data-bind="template: { foreach: Phases, name: 'row-template'}"> 
    </tbody> 

    <script type="text\html" id="row-template"> 
    <tr>...</tr> 
    </script> 
+0

表本身顯示正常,所有的數據綁定工作。 applyBindings調用在別處完成。 – tnktnk

+0

那麼我不確定你的問題是什麼。它正在顯示數據,但缺少一行? –

+0

當用戶單擊執行HTTP回發到服務器的任何按鈕時,將從該表中刪除一行。我已經將問題隔離到了我添加的viewmodel代碼,但是我看不到任何代碼會影響表中行數的方式。 – tnktnk