如何补充WinJS.Class

时间:2013-01-21 01:58:07

标签: javascript windows-8 windows-store-apps winjs

我正在序列化并存储从WinJS.Class创建的对象,如下所示:

var myClass = WinJS.Class.define(...);
var myObject = new myClass();
var serialized = JSON.stringify(myObject);
//store the object

后来我将对象从存储中拉出来,我想反序列化它并将其转换为myClass。这可能是开箱即用的WinJS还是我需要为我的类创建一个能够获取可以将其转换为新对象的对象的构造函数?

我还没有进入TypeScript,我认为在这种情况下会有所帮助,但在那之前我想知道如何使用纯JavaScript / WinJS来实现它。

5 个答案:

答案 0 :(得分:1)

有几种方法可以解决这个问题,而且没有一种方法可以解决WinJS问题。简单地说:JSON序列化只对obje值进行序列化和反序列化,而不是其方法,原型或其他类型信息。

选项1:将值复制到班级的新实例 这通常最好通过让构造函数将反序列化的对象作为参数并将数据复制到新实例来实现。

这有各种各样的变化。使用对象构造函数通常是性能最佳的,因为这通常使JS引擎能够将更多数量的优化应用于对象。

WinJS.UI.setOptions在这里很有用,或者你可以使用这样的简单循环来复制数据:

var keys = Object.keys(source);
for (var i = 0, len = keys.length; i < len; i++) {
    var key = keys[i];
    destination[key] = source[key];
}

选项2:设置__proto __ 警告:这可能会产生严重的性能影响,因此在某些情况下不合适。但偶尔它会很方便。

Object.setPrototypeOf(myObject, myClass.prototype);

请注意,setPrototypeOf相对较新。它存在于Win8.1上的Web应用程序(我猜这是关于)和IE 11中,但在Safari中不可用,例如。在较旧的浏览器/ Safari上,分配 proto 是等效的(但如果可用,setPrototypeOf更好)。

这会将myClass中的方法附加到对象,但除了负面的性能影响之外,还不会在对象上运行构造函数 - 因此它仍然可能与您最初序列化的对象完全不同。

其他有用的东西:JSON“复活” JSON.parse采用可选的第二个参数,称为“reviver”。这使您可以提供一个函数,该函数可以转换要反序列化的JSON的每个节点。例如,这对于将序列化日期重新水化为JavaScript Date对象非常有用。它还有机会转换最顶层的对象,这在某些情况下可能有用,可以将反序列化的对象转换为您想要的“类”。

答案 1 :(得分:0)

Javascript是一种动态语言,因此我认为您不需要强制转换反序列化对象,只需将其视为myClass类型即可。希望它可以帮到你。

答案 2 :(得分:0)

您应该考虑使用'Options'构造函数模式,其中选项值是反序列化的对象:

// MovieModel Constructor
// ----------------------
function MovieModel(options) {
    this._titleValue = options.title || "Sample Title";
}

电影方法关闭的地方是这样的:

// MovieModel Methods
// ------------------
var movieModelMethods = {
    title: {
        get: function () {
            return this._titleValue;
        },
        set: function (val) {
            this._titleValue = val;
            this.dispatchEvent("title");
        }
    }
};

答案 3 :(得分:0)

由于WinJS类定义只能指定一个构造函数(据我所知),您可以使用静态成员来定义将序列化数据作为参数的工厂函数。这个工厂方法实际上会创建一个新实例,并将逐个设置值并返回新对象。

它具有一些优点,例如您可以在增强应用程序时实际管理数据结构更改... 缺点是你不能一直写新的MySuperClass()......

...
// let's suppose we already called JSON.parse(data);
create: function(serializedData) {
    var newObj = new MySuperClass();
    newObj.name = serializedData.name || "";
    newObj.color = serializedData.color || "";
    return newObj;
}

然后你会在应用程序的其他地方打电话:

var myInstance = MySuperClass.create(serializedDataFromfile);

答案 4 :(得分:-2)

您应该只能在将JSON.parse拉出本地存储后调用它:

var myObject2; myObject2 = JSON.parse(localStorage [“mySeriazliedObject”];