我为我的Ember.js应用程序编写了我的所有者适配器和序列化程序。我遵循JSON API标准(ID格式),因此我的大多数JSON看起来像这样:
{
"id": "2364",
"name": "Test",
"links": {
"single": "2834",
"multiple": ["2292", "9584", "8475"]
}
}
但是,我的所有关系都是懒惰加载的(我将async
属性定义为true
)。这是必需的,因为一些记录可能变得非常大。问题是当我尝试序列化模型时。如果尚未加载关系,我将无法获取相关模型的ID。所以我要说我编辑上面模型的名称并尝试保存它。我会得到这个JSON:
{
"id": "2364",
"name": "This has been edited",
"links": {
"single": null,
"multiple": []
}
}
由于尚未加载关系,因此它为我提供了空值。但是,因为关系尚未编辑,所以它们应该与它们进入时完全相同。要获取该数据,我可以使用model.get('data')
并获取包含最初从中返回的ID的对象服务器。因此,如果我知道某个关系已被卸载,我可以致电model.get('data.relationshipName')
并获取原始ID。
现在真正的问题是:如果关系被完全加载,我想在它被编辑时序列化它。但是,如果不完全加载,我不想尝试加载它。在这种情况下,我可以从data
属性中获取ID。那么,如何在不加载关系的情况下确定关系是否已加载?
答案 0 :(得分:0)
让所有模型都从单个基类继承。在该基类中,您想要做三件事。首先,在init
方法中,在实例上创建一个哈希(对象)(将其留空)。接下来,覆盖get
方法,如果用户尝试访问其中一个关系,请更新您创建的哈希以反映该方法。最后在类中添加类似wasRelationshipAccessed(name)
的方法以从哈希中读取。这将告诉您确切地访问了哪些关系,以及通过消除过程,哪些不是。
同样在该基类中,让init
方法创建另一个哈希。这个将存储来自服务器的关系的原始值。我打电话给我originalLinks
。
覆盖DS.Store
并将其分配给App.Store
。在该类中,重写push
方法。在覆盖中,调用this._super.apply(this, arguments)
并保存返回值。该返回值是记录。既然您同时拥有服务器和记录中的数据,请将服务器中的关系插入上面的originalLinks
哈希值。
最后,在序列化程序中,使用wasRelationshipAccessed
功能。如果访问了该关系,则会加载它。如果未访问,请从originalLinks
哈希。
这就是它的全部内容。如果您要这样做,我高度建议您为序列化程序,适配器和商店的那部分编写单元测试。这将确保您能够捕获对Ember-Data内部的任何更改。