Knockoutjs - viewmodel中的函数导致不合需要的递归

时间:2013-05-03 08:10:08

标签: serialization recursion knockout.js

在我的Knockout视图模型中,我有一个Save()函数,它发送一个jQuery POST请求。在此POST请求中,调用ko.toJS(this)

每当我调用此Save函数时,浏览器都会无响应,并最终告诉我递归过多。在调试(通过使用断点)时,我发现当我调用JS()时,它似乎对对象进行了某种程度的克隆,并且在执行此克隆时,它调用Save()函数,该函数又调用JS()。 ..而且还有递归。

为什么会发生这种情况,有没有办法在不使用toJSON()的情况下避免它?

[我有关于toJSON的另一个问题,这解释了为什么我不想使用它。]

为了完整起见,这是我的观点模型。

function vmDictionary(dict) {

    if (dict === null || dict === undefined) {
        return;
    }

    var self = this;

    // directly-assigned variables
    self.Concepts = new vmConcepts(dict.Concepts);
    self.Deleted = ko.observable(dict.Deleted);
    self.Description = ko.observable(dict.Description);
    self.IncludeInSearch = ko.observable(true);
    self.ID = ko.observable(dict.ID);
    self.Languages = ko.observableArray(dict.Languages);
    self.LastUpdate = new vmChangeRecord(dict.LastUpdate);
    self.Name = ko.observable(dict.Name);
    self.Public = ko.observable(dict.Public);

    self.TemplateName = function(observable, bindingContext) {
        return "dictionary-template";
    };

    // computed variables
    self.PublicText = ko.computed(function() {
        return sp.Utils.Localize(self.Public
            ? "Public"
            : "Private");
    });

    // exposed functions
    self.Save = function () {
        $.ajax({
            data: ko.toJSON(self),
            dataType: "json",
            type: "POST",
            url: [...],
            statusCode: {
                200: function (response) {
                    console.log(response);
                }
            },
            error: function (xmlHttpRequest, textStatus, errorThrown) {
                console.log(xmlHttpRequest);
                console.log(textStatus);
                console.log(errorThrown);
            }
        });
    };
}

UPDATE:添加了整个视图模型(上图)。

1 个答案:

答案 0 :(得分:0)

你必须做错事,对我来说有点小提琴

http://jsfiddle.net/brN9s/

ViewModel = function() {
    this.someData = ko.observable("Test");
    this.dto = ko.observable();
};

ViewModel.prototype = {
    Save: function() {
        this.dto(ko.toJS(this));        
    }
};

var viewModel = new ViewModel();
ko.applyBindings(viewModel);
viewModel.Save();