我正在尝试编写代码以对嵌入的记录进行一般性的标准化。我试图在序列化程序的“normalizePayload”方法中执行此操作,因为在store.pushPayload调用中未调用“extractObject”和“extractArray”(我正在使用pushPayload预先加载数据)。
这是我的代码:
App.ApplicationSerializer = DS.ActiveModelSerializer.reopen
embeddedRelationships: []
extractHasOne: (payload, relationship_name) ->
object = payload[relationship_name]
objectId = object['id']
payload["#{relationship_name}_id"] = objectId
delete payload[relationship_name]
return object
extractHasMany: (payload, relationship_name) ->
objects = payload[relationship_name]
objectIds = objects.mapProperty('id')
payload["#{Ember.Inflector.inflector.singularize(relationship_name)}_ids"] = objectIds
delete payload[relationship_name]
return objects
extractRelationships: (payload) ->
extracted_objects = {}
this.embeddedRelationships.forEach((relationship_name) ->
relationship_payload = payload[relationship_name]
if relationship_payload instanceof Object
# has one
extracted_objects[relationship_name] = this.extractHasOne(relationship_payload, relationship_name)
else if relationship_payload instanceof Array
# has many
extracted_objects[relationship_name] = this.extractHasMany(relationship_payload, relationship_name)
, this)
return extracted_objects
normalizePayload: (type, payload) ->
if payload[type]?
# single object
this.extractRelationships(payload[type])
else if payload[Ember.Inflector.inflector.pluralize(type)]?
# many objects
payload[Ember.Inflector.inflector.pluralize(type)].forEach((object_payload) ->
this.extractRelationships(object_payload)
, this)
注意:尚未完成,因为我尚未合并所有提取的对象并对其进行侧面加载。
无论哪种情况,其想法都是在子类中,我用表示该模型必须规范化的关系的字符串列表覆盖“嵌入式关系”。
我遇到的问题很简单:正在使用空的“类型”值调用“normalizePayload”。
我正在像这样预加载数据:
this.store.pushPayload('category', window.preloadCategories)
这是一个 Ember 错误,还是我错过了一些东西?
最佳答案
pushPayload
接受类型并获取该serializer
,然后在不接受类型的自定义序列化程序上调用pushPayload
,因此没有类型传递给normalizePayload
。
我建议为Category
创建一个自定义序列化器,而不是Application
,然后您将知道其类别类型。
其背后的原因是pushPayload适用于推送多个单一类型(又称有效负载不仅仅是Category
或Post
商店中的pushPayload
/**
Push some raw data into the store.
The data will be automatically deserialized using the
serializer for the `type` param.
This method can be used both to push in brand new
records, as well as to update existing records.
You can push in more than one type of object at once.
All objects should be in the format expected by the
serializer.
```js
App.ApplicationSerializer = DS.ActiveModelSerializer;
var pushData = {
posts: [
{id: 1, post_title: "Great post", comment_ids: [2]}
],
comments: [
{id: 2, comment_body: "Insightful comment"}
]
}
store.pushPayload('post', pushData);
```
@method pushPayload
@param {String} type
@param {Object} payload
*/
pushPayload: function (type, payload) {
var serializer;
if (!payload) {
payload = type;
serializer = defaultSerializer(this.container);
Ember.assert("You cannot use `store#pushPayload` without a type unless your default serializer defines `pushPayload`", serializer.pushPayload);
} else {
serializer = this.serializerFor(type);
}
serializer.pushPayload(this, payload);
},
序列化器上的pushPayload It will first normalize the payload, so you can use this to push
in data streaming in from your server structured the same way
that fetches and saves are structured.
@method pushPayload
@param {DS.Store} store
@param {Object} payload
*/
pushPayload: function(store, payload) {
payload = this.normalizePayload(null, payload);
for (var prop in payload) {
var typeName = this.typeForRoot(prop),
type = store.modelFor(typeName);
/*jshint loopfunc:true*/
var normalizedArray = map.call(payload[prop], function(hash) {
return this.normalize(type, hash, prop);
}, this);
store.pushMany(typeName, normalizedArray);
}
},