2016-08-05 71 views
0

後計算觀測映射我有一個Ajax調用視圖模型來保存數據:淘汰賽:不能Ajax調用

ViewModel = function (data) { 
    contractsAutocompleteUrl = data.ContractsAutocompleteUrl; 
    var self = this; 
    ko.mapping.fromJS(data, lineMapping, self); 

    self.save = function() { 
     self.isBeingSaved(true); 
     $.ajax({ 
      url: data.SaveUrl, 
      type: "POST", 
      data: ko.toJSON(self), 
      contentType: "application/json", 
      success: function(data) { 
       if (data.viewModel != null) { 
        ko.mapping.fromJS(data.viewModel, lineMapping, self); 
       }; 
      } 
     }); 
    }, 

我有一些計算的變量:

self.TotalSaturdayHrs = ko.pureComputed(function() { 
    var result = 0; 
    ko.utils.arrayForEach(self.Lines(), 
     function(line) { 
      result = addNumbers(result, line.SaturdayHrs()); 
     }); 
    return result; 
}), 
self.TotalSundayHrs = ko.pureComputed(function() { 
    var result = 0; 
    ko.utils.arrayForEach(self.Lines(), 
     function(line) { 
      result = addNumbers(result, line.SundayHrs()); 
     }); 
    return result; 
}), 

。 。 。 (一路星期五)

而且一個計算GrandTotal:

self.GrandTotalHrs = ko.pureComputed(function() { 
    var result = addNumbers(0, self.TotalSaturdayHrs()); 
    result = addNumbers(result, self.TotalSundayHrs()); 
    result = addNumbers(result, self.TotalMondayHrs()); 
    result = addNumbers(result, self.TotalTuesdayHrs()); 
    result = addNumbers(result, self.TotalWednesdayHrs()); 
    result = addNumbers(result, self.TotalThursdayHrs()); 
    result = addNumbers(result, self.TotalFridayHrs()); 
    return result; 
}), 

Ajax調用後,現在,計算觀測TotalSaturdayHrs不再計算的觀測,他們根本性質,因此我GrandTotal計算拋出一個例外。 這是爲什麼,我該如何解決這個問題?

+1

我的第一個猜測是服務器在POST響應中發送'TotalSaturdayHrs'(etc)屬性,隨後映射插件將覆蓋您的視圖模型。 – Tomalak

+0

不嚴格相關,但請告訴我'addNumbers()'看起來不像'function addNumbers(a,b){return a + b; }'。 – Tomalak

+0

var addNumbers = function(result,number)if(number === null || number ===「」){ return result; } 返回結果+ parseFloat(number); } – arame3333

回答

1

您的.save()功能應該是什麼樣子的(我有一種預感,這將解決您的問題):

ViewModel = function (data) { 
    var self = this, 
     contractsAutocompleteUrl = data.ContractsAutocompleteUrl; 

    self.isBeingSaved = ko.observable(false); 
    self.Lines = ko.observableArray(); 

    ko.mapping.fromJS(data, lineMapping, self); 

    self.save = function() { 
     self.isBeingSaved(true); 
     return $.ajax({ 
      url: data.SaveUrl, 
      type: "POST", 
      data: ko.mapping.toJSON(self), // !!! 
      contentType: "application/json" 
     }).done(function (data) { 
      if (!data.viewModel) return; 
      ko.mapping.fromJS(data.viewModel, lineMapping, self); 
     }).fail(function (jqXhr, status, error) { 
      // error handling 
     }).always(function() { 
      self.isBeingSaved(false); 
     }); 
    }; 
} 

ko.mapping.toJSON()只會把這些屬性JSON也走進了原來的映射。另一方面,ko.toJSON()轉換所有屬性,即使是計算的如TotalSundayHrs

我的猜測是服務器返回它在POST中收到的同一個JSON對象,並且完成所有應該計算的屬性,如TotalSundayHrs - 然後在響應處理程序中混淆映射。

+0

我應該如何設置Total字段,以便在返回客戶端時可以通過計算函數重新計算它們? – arame3333

+0

如果我將計算函數的代碼複製並粘貼到done子句中,那麼它就起作用。但我不想這樣做。 – arame3333

+0

計算出的「全部」屬性可以保持原樣。你需要確保**服務器響應不包含相同名稱的屬性(比如'TotalSundayHrs')**或**你的映射設置('lineMapping')被明確配置爲忽略這些屬性(請參閱[documentation](http://knockoutjs.com/documentation/plugins-mapping.html#ignoring-certain-properties-using-ignore))。 – Tomalak