0

我看到对 Spine 中的子类模型使用 JSON.stringify 的奇怪行为,我希望有人能提供帮助!

这是我们在一个项目中获得的一些代码的简化摘录:

define([
    "jquery",
    "underscore"
],

function ($, _) {
    var SuperClass = Spine.Model.sub();
    SuperClass.configure("SuperClass", "SuperClassProperty");

    var SubClass = SuperClass.sub();
    SubClass.configure("SubClass", "SubClassProperty");

    var instance = new SubClass({ SuperClassProperty: "Super", SubClassProperty: "Sub" });
    console.log(instance);

    var json = JSON.stringify(instance);
    console.log(json);
});

“console.log(instance)”正在打印出我在这种情况下所期望的:

result
    SubClassProperty: "Sub"
    SuperClassProperty: "Super"
    cid: "c-0"
    __proto__: ctor

但是,当我对实例使用 JSON.stringify 时,这就是我返回的全部内容:

{"SubClassProperty":"Sub"} 

为什么 SuperClassProperty 不包含在 stringify 中?

我通过强制 JSON2 覆盖 Chrome 的原生 JSON 对象,排除了 JSON.stringify 方法的问题;两种实现都产生相同的结果。看起来 stringify 将委托给对象上的“toJSON”函数(如果有的话)——在这种情况下有(作为 Spine 的一部分)。

因此,看起来(a)这是 Spine 中的一个错误,或者(b)我做错了什么,这是更有可能的选择。

我知道我也可以通过在子类上重新配置超类属性来解决这个问题:

SubClass.configure("SubClass", "SuperClassProperty", "SubClassProperty");

然而,这对我来说似乎违反直觉(子类化有什么意义?),所以我希望这不是答案。

更新:我已经通过 Spine 源代码进行了一些调试,据我所知,问题是我配置子类的方式:

    var SubClass = SuperClass.sub();
    SubClass.configure("SubClass", "SubClassProperty");

在这里调用“配置”似乎消除了超类的属性。Model原型上的“toJSON”实现如下:

Model.prototype.toJSON = function() {
    return this.attributes();
};

由于在配置 SubClass 时会重置属性集合,因此在 JSON 字符串中不会出现 SuperClass 属性。

我不确定我是否不应该在子类对象上调用“配置”,但我在文档中找不到任何地方说我应该做其他事情 - 这是我可以找到的子类模型的唯一参考(来自:http ://spinejs.com/docs/models ):

模型也可以很容易地被子类化:

var User = Contact.sub();
User.configure("User");
4

1 回答 1

0

正如我所怀疑的,问题出在我使用 Spine 的方式上。Spine 的作者的这条评论推断在子类上使用“配置”将消除超类的属性。我不得不承认我不明白为什么会这样;这对我来说似乎违反直觉,但至少我现在知道这不是一个错误。

万一其他人遇到这个问题,我解决它的方法是将我自己的扩展方法添加到 Spine 模型中,如下所示:

(function () {
    var Model = Spine.Model;

    Model.configureSub = function () {
        var baseAttributes = this.attributes.slice();
        this.configure.apply(this, arguments);

        this.attributes = baseAttributes.concat(this.attributes);
        return this;
    };
})();

现在配置我的子类:

var SubClass = SuperClass.sub();
SubClass.configureSub("SubClass", "SubClassProperty");

现在我的 JSON 正确地反映了超类和子类的属性。

于 2012-10-31T03:39:06.930 回答