【问题标题】:Troubles with parsing nested knockout viewmodels to JSON将嵌套的淘汰视图模型解析为 JSON 的问题
【发布时间】:2013-01-16 18:47:32
【问题描述】:

问题

在我工作和探索 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 时才会发生这种情况。

【问题讨论】:

  • 嗯,这个问题的原因完全是我自己的错。除此之外,如果我必须在没有 KO 的情况下编写当前应用程序,我可能无法使其成为单页应用程序。代码至少要长 5 倍,而且更复杂。
  • 你得到了我的好奇心......看我制作了这个小型数据可视化应用程序,只处理 5mb 的原始数据和大约 200 种不同的视图组合(2 个视图模式,3 个选择标准,具有不同的选项取决于在其他选项中选择的选项);我使用 jquery 手动构建了我的索引算法和事件,生成的脚本在 ie6+ 和其余部分中工作时缩小了 23kb;所以对你来说,比 ko 大 5 倍就像缩小了 200kb 这就像我的应用程序 * 10 = 20 种查看模式或 60 种选择,这取决于彼此,在单个页面中有 2000 种不同的查看组合......哇哦,那是巨大的。

标签: javascript jquery knockout.js viewmodel knockout-2.0


【解决方案1】:

有几种方法可以处理这种情况。 KO 的ko.toJS 部分可以正确处理此问题。最终是JSON.stringify(在ko.toJSON 中调用ko.toJS 导致错误。

您的原型上的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 值放在函数后面(可以作为可观察对象的子属性)。当你的结构被ko.toJS 转换成一个普通的 JS 对象时,函数的所有子属性都会丢失。

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);
        });
    }
};

【讨论】:

  • 因为这只是代码的简化版本,而在原始版本上我有更多的嵌套视图模型,更正 toJSON 解决了​​问题。谢谢!
猜你喜欢
  • 2013-07-08
  • 2015-08-17
  • 2013-05-31
  • 1970-01-01
  • 2014-06-25
  • 1970-01-01
  • 2013-02-19
  • 2014-12-11
相关资源
最近更新 更多