在我的应用程序中,我在另一个类中组合了一个coffeescript类( class A的一个实例包含一个对象数组,这些对象的一个属性是class B的实例)。然后我发现了cmather's video about EJSON,并认为在我的对象中使用它会很酷。然而,Meteor似乎不能正确处理位于其他EJSON对象中的class A对象--可以将该class A保存到数据存储中,并且在被查询时作为一个class B返回,但是class B最终作为一个Object而不是class B实例从集合中返回。当我运行一些测试代码时,嵌入式EJSON对象一开始似乎可以工作(在初始collection.insert()之后),但它在刷新浏览器后返回纯Object,甚至返回结构不正确的对象。我的理论是,minimongo和服务器端mongo的行为存在一些不匹配,但也可能有其他原因。
那么,有没有办法将一个EJSON对象嵌入到另一个EJSON对象中呢?也许我的代码中有一个缺陷?这只是一个坏主意吗?我可以让class A在它的constructor中自己实例化class B项,但是看起来EJSON应该能够处理这个问题。如果你认为这是一个bug,我很乐意在github上提交一个问题,但我想我应该先在这里检查一下。
如果需要代码来尝试这一点,可以尝试下面的代码,它设置了两个基本上相同的类,一个称为Inner,另一个称为Outer,并创建了一个名为outer的Outer实例,其中包含一个Inner实例作为属性innerHere。在控制台中,键入testCollection.insert({outerHere: outer}。现在,testCollection.findOne()可能会为您提供一个对象,其中该对象的innerHere属性是Inner的正确实例,但是如果您刷新浏览器,相同的命令可能会返回不同的内容。
如果这个问题很难理解,请让我知道,我会试着澄清。
设置它的代码(只需在新项目的根目录中创建一个.coffee文件):
@testCollection = new Meteor.Collection("test")
class @Outer
constructor: (value) ->
@value = value
clone: ->
new Outer(@value)
equals: (other) ->
_.isEqual(@, other)
typeName: ->
"Outer"
toJSONValue: ->
value: @value
EJSON.addType("Outer", (value)->
new Outer(value)
)
class @Inner
constructor: (value) ->
@value = value
clone: ->
new Inner(@value)
equals: (other) ->
_.isEqual(@, other)
typeName: ->
"Inner"
toJSONValue: ->
value: @value
EJSON.addType("Inner", (value)->
new Inner(value)
)
@outer = new Outer({innerHere: new Inner ("inner value")})发布于 2013-08-04 13:47:13
当EJSON调用外部类型的toJSONValue时,它不会递归到结果中以自动检测内部类型。同样,在fromJSONValue (传递给EJSON.addType方法的函数)中,您将获得一个JSON值对象( toJSONValue返回的任何结果),并由您对其执行某些操作。为了更好地理解转换过程,让我们给出一个给定类的示例。
假设我们将要通过网络传递您的外部类的一个实例(例如作为方法调用中的参数)。
myOuter = new Outer({innerHere: new Inner('inner value')});Meteor将遵循与以下类似的步骤:
EJSON.stringify(myOuter) =>
var jsonValue = EJSON.toJSONValue(myOuter);
var json = JSON.stringify(jsonValue);对EJSON.toJSONValue的调用将创建一个具有$type和$value属性的新对象。$value属性的值是对对象调用toJSONValue的结果。所以jsonValue是一个看起来像这样的对象:
{
$type: 'Outer',
$value: {
innerHere: {
value: 'inner value'
}
}
}调用JSON.stringify(jsonValue)会得到一个如下所示的JSON字符串:
"{"$type":"Outer","$value":{"value":{"innerHere":{"value":"inner value"}}}}"如果您希望innerHere属性是EJSON类型,我们还需要在该对象上调用EJSON.toJSONValue (从外部的toJSONValue方法)。例如(在js中):
Outer.prototype.toJSONValue = function () {
return {
value: EJSON.toJSONValue(this.value)
};
};现在假设我们创建一个新的外部实例,如下所示:
myOuter = new Outer(new Inner('inner value'));然后我们调用EJSON.toJSONValue(myOuter):
{
$type: 'Outer',
$value: {
value: {
$type: 'Inner',
$value: {
value: 'inner value'
}
}
}
}通过网络发送的json字符串如下所示:
"{"$type":"Outer","$value":{"value":{"$type":"Inner","$value":{"value":"inner value"}}}}"好了,那么现在我们的fromJSONValue函数中发生了什么?我们将得到一个与toJSONValue返回的对象相似的对象。因此,在将每个已知为自定义类型的属性传递给外部的构造函数之前,我们需要对这些属性调用EJSON.fromJSONValue。在此示例中,您可以执行以下操作:
EJSON.addType('Outer', function (jsonValue) {
var inner = EJSON.fromJSONValue(jsonValue.value);
return new Outer(inner);
});可用于测试序列化和反序列化的两种方法是:
var serialized = EJSON.stringify(myOuter);
var deserialized = EJSON.parse(serialized); // is the resulting object what you expect?希望这能有所帮助!
https://stackoverflow.com/questions/17598811
复制相似问题