【问题标题】:Avoid error of cyclic value in view, knockout避免视图中循环值的错误,淘汰赛
【发布时间】:2015-09-03 18:43:41
【问题描述】:

我的淘汰赛模型(淘汰赛 3.3.0 版)是这样的:

var Node=   function(id,name,parentNode) {
            var self = this;
            self.id= ko.observable(id);
            //more here...
            self.nodes = ko.observableArray([]);
            self.parentNode = parentNode;
        }

当这个模型被绑定到一个视图时,敲除在控制台中抛出一个错误(非破坏性错误):

TypeError: 循环对象值

...m http://www.json.org/json2.js");返回 E.stringify(a.a.c(b),c,g)},zc:function(c...

knockout-3.3.0.js(第 20 行,第 344 列)

所以,我假设在内部某个地方,敲除调用 JSON.stringify 方法。 通过结合herehere 的答案,我得出结论,如果我在我的模型中添加一个“toJSON”方法,其中我排除了“parentNode”属性,错误就会消失。确实如此。

我的 toJSON 函数:

self.toJSON = function(){
                    return {
                        id: self.id(),
                        name: self.name(),
                        //exclude parentNode
                        nodes: ko.toJSON(self.nodes())
                    };
                }

所以我的问题是:有没有更有效的方法来编写这个函数以使其更通用?我想包含所有(未知)属性,不包括少数(已知)属性。

在模型上调用 ko.toJSON,然后按照第一个链接的建议删除属性是行不通的,因为循环引用。那么还有其他选择吗?

编辑: 绑定时隐含的对 JSON 的调用是由另一个 ko 插件进行的,但它实际上可以是任何东西。我已经设置了一个孤立的小提琴来演示这个问题,以及我在这里的临时解决方案:http://jsfiddle.net/zq09znLa/1/

【问题讨论】:

  • jsfiddle.net/LkqTU/24754 处查看工作示例。让我知道干杯
  • @supercool 抱歉,您的回答与我的问题无关。查看我的编辑,我添加了一个可重现的小提琴。
  • 通过 id 在字典中注册节点,然后将节点存储为 id 数组,并计算以生成实际的节点列表。同样,存储父节点 ID 并计算(如果需要)来获取节点本身。
  • 您的示例中的小提琴不起作用(至少在 Chrome 中不起作用),KoLite 未加载,因为未设置服务器响应 MIME 类型(来自 raw.github.com)
  • @Tyblitz 小提琴不应该工作:查看控制台错误和小提琴 cmets。如果您注释掉相应的部分,它将起作用。也在 chrome 上测试过。

标签: javascript json knockout.js


【解决方案1】:

您可以使用替换功能(请参阅solution here)排除不需要的键:

var excludeKeys = {
    parentNode: true
};

这有点尴尬,因为你必须暂时删除 self.toJSON 以避免无限递归。

self.toJSON = function () {
    var save = self.toJSON;
    delete self.toJSON;
    var result = ko.toJSON(self, function (key, value) {
        if (key in excludeKeys) return null;
        return value;
    });
    self.toJSON = save;
    return result;
};

我已更新您的小提琴,使其在 Chrome 中运行并演示解决方案: http://jsfiddle.net/zq09znLa/4/

更新:我制作了一个版本,其中 toJSON 定义为原型中的空函数。它通过取消序列化使程序成功运行(就具有预期的输出而言)。

Node.prototype = {
    toJSON: function () {}
};

我想制作一个驻留原型的 toJSON,但它并没有测试 toJSON 是否在做正确的事情。

http://jsfiddle.net/2o7cnzL2/1/

【讨论】:

  • 暂时删除“toJSON”的那部分非常棒。谢谢!
  • @pkExec JSFiddle 的 TidyUp 弄乱了 HTML,因此已修复。另外,使用原型而不是本地 toJSON 的新解决方案
  • 不,您在小提琴中最新的使序列化无效的编辑不是所要求的。为未来的读者更好地保留它(减去 HTML 错误)。
  • 同意它不按要求做。我认为指出小提琴不测试序列化是否实际正确完成是有用的。
猜你喜欢
  • 1970-01-01
  • 2019-10-03
  • 2013-11-25
  • 1970-01-01
  • 1970-01-01
  • 2013-06-10
  • 1970-01-01
  • 2013-03-19
  • 2013-06-19
相关资源
最近更新 更多