2

问题

当我在工作和探索 knockoutjs 时,我在某个时候陷入了困境。我想将视图模型(和底层视图模型)序列化为 JSON。这将导致无限循环,因为子视图模型具有引用父视图模型的属性。解决此问题的最佳做法是什么?

编码

var Partner = function (parent) {
    var self = this;
    self.parent = parent;
    self.name = ko.observable('');
}

var ProjectViewModel = function () {
    var self = this;
    self.nr = ko.observable(0);
    self.tite = ko.observable('');
    self.partners = ko.observableArray();            

    self.addPartner = function () { self.partners.push(new Partner(self)) };
    self.removePartner = function (c) { self.partners.remove(c) };
};
var vm = new ProjectViewModel();
ko.applyBindings(vm);


$("#button").click(function () {
    alert(ko.toJSON(vm));
}

到目前为止我尝试了什么

我尝试在合作伙伴视图模型中添加以下方法:

Partner.prototype.toJSON = function () {
            var copy = ko.toJS(self);
            delete copy.parent;
            return copy;
        }

这仅适用于一个合作伙伴,如果 ProjectViewModel 有多个合作伙伴,则每个合作伙伴都将具有与最后一个合作伙伴相同的值。仅当我想将其序列化为 JSON 时才会发生这种情况。

4

1 回答 1

2

有几种方法可以处理这种情况。KO的ko.toJS部分正确地处理了这个。它最终是JSON.stringifyko.toJSko.toJSON导致错误之后调用。

toJSON在原型上的方法非常接近,除了您想要处理this而不是self.

所以,它看起来像:

Partner.prototype.toJSON = function() {
  var copy = ko.toJS(this);
  delete copy.parent;
  return copy; 
};

其他处理方法:

1-实际上不要将您的父对象存储在子对象上,而只是根据传递给构造函数的参数直接在任何处理程序中引用它。

var Partner = function (parent) {
    var self = this;
    self.name = ko.observable(name);

    self.doSomething = function() {
        //can use "parent" directly here without storing it anywhere
    };
};

2-“隐藏”你的父母参考

var Partner = function (parent) {
    var self = this;
    self.meta = function() {};
    self.meta.parent = parent;
    self.name = ko.observable(name);    
};

您可以将您的parent价值放在一个函数后面(可以作为可观察对象的子属性)。当你的结构通过 转换为普通的 JS 对象时ko.toJS,函数的任何子属性都将丢失。

3-改变你的应用程序的结构,这取决于你想要做什么。假设父母想在孩子改名时做出反应。您可以传入一个回调,设置订阅,并在它更改时执行它

var Partner = function (nameChangedCallback) {
    var self = this;
    self.name = ko.observable(name);    

    if (typeof nameChangedCallback == "function") {
        self.name.subscribe(function() {
           nameChangedCallback.call(self, self);
        });
    }
};
于 2013-01-16T20:15:35.303 回答