Knockout:在Ajax调用之后无法映射计算的observable

时间:2016-08-05 11:20:52

标签: ajax knockout.js

我有一个带有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调用之后,计算的observables TotalSaturdayHrs不再是计算的observable,它们只是属性,因此我的GrandTotal计算会引发异常。 为什么这样,我该如何解决这个问题?

1 个答案:

答案 0 :(得分: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 - 这会混淆你的映射响应处理程序。