我正在开发一个Ember应用程序,它从Facebook的Graph和Rails API中聚合内容。由于我编写了Rails API并控制了JSON格式,所以我在让Ember应用程序查询和服务该内容方面没有任何问题。然而,我在规范Facebook内容方面遇到了一些困难。
举个例子,下面是Facebook提供的一些Feed JSON:
{
"data": [
{
"id": "604231966385537_765079483634117",
"type": "link",
"message": "They're watching you...",
"from": {
"name": "Kristian Twombly",
"id": "10154089935544635"
}
},
{
"id": "604231966385537_765057943636271",
"type": "status",
"message": "The boss's new ride. He saw mine and had to have one.",
"from": {
"name": "Walter Johnson",
"id": "10206908914060788"
}
},
{
"id": "604231966385537_764751447000254",
"type": "photo",
"message": "Found 1 at Target Apple Valley",
"from": {
"name": "Quentin Waterkamp",
"id": "10210042929332132"
},
"comments": {
"data": [
{
"created_time": "2016-09-01T01:33:55+0000",
"from": {
"name": "Riley Richardson",
"id": "1189835384423610"
},
"message": "Are these rare to find or something?",
"id": "764829800325752"
},
{
"created_time": "2016-09-01T04:33:44+0000",
"from": {
"name": "Quentin Waterkamp",
"id": "10210042929332132"
},
"message": "seems to be I was also at a Walmart today and didn't see one and the other Target in Apple Valley didn't have any the other day.",
"id": "764893193652746"
}
],
"paging": {
"cursors": {
"before": "WTI5dGJXVnVkRjlqZAFhKemIzSTZAOelkwT0RJNU9EQXdNekkxTnpVeU9qRTBOekkyT1RNMk16VT0ZD",
"after": "WTI5dGJXVnVkRjlqZAFhKemIzSTZAOelkwT0Rrek1Ua3pOalV5TnpRMk9qRTBOekkzTURRME1qUT0ZD"
}
}
},
}
],
"paging": {
"previous": "https://graph.facebook.com/v2.7/604231966385537/feed?fields=id,type,message,from,comments&icon_size=16&since=1472731871&access_token=1333570303337296|ssnHtq9p3DuFAxX23XRx7Dc1reQ&limit=25&__paging_token=enc_AdBfsb6FAxWTzuRVAHs3OujbQ3O0Ry2z7QIHq40E45FaLZAyf2mYy888ZASAEiw7D0N31xuAij5ZBsYVZBeVPZAXz5HfDAN2ZAklhsRHRjMu7qLzdODgZDZD&__previous=1",
"next": "https://graph.facebook.com/v2.7/604231966385537/feed?fields=id,type,message,from,comments&icon_size=16&access_token=1333570303337296|ssnHtq9p3DuFAxX23XRx7Dc1reQ&limit=25&until=1472348927&__paging_token=enc_AdBhRIcyqcv8ZByyC5GnCv2PfoIzySxiZCSdRw3LoOCE2gj51ZCMv9l7OPGWLcrJeHal9Tna2rhsGEul5jEzN93dBA1BXhzdgZCmOOT9y8OqDZCSh2wZDZD"
}
}考虑到根元素是data,我最初假设它是在JSON规范中提供的。但是,缺少attributes键意味着默认的Ember JSONAPISerializer在没有修改的情况下无法工作。相反,data键的存在意味着JSONSerializer也不能正确解析JSON。
我很难让JSON正确地序列化所有对象。如果我删除comments属性的/app/models/facebook-photo.js,我可以得到顶级对象(如照片,链接,状态)填充(我确认这一点在Chrome中使用Ember检查器)。但是,我无法序列化用于hasMany的嵌入式comments关系。当我试图运行我的Ember应用程序时,我现在得到了以下错误:
提取,许多不能读取属性'id‘的null
有人能帮助我理解如何从Facebook中正确地规范化JSON吗?此外,如何正确配置comments的comments关系
作为参考,下面是我的最新代码(我只包含了用于简化的facebook-photo代码):
请注意:我已经使用了modelNameFromPayloadKey和payloadKeyFromModelName序列化器方法,因为我为Facebook的模型在类型名称后面有“facebook-”(模型名与我其他API的类型相冲突)。
/app/routes/index.js
import Ember from 'ember';
export default Ember.Route.extend({
model() {
return Ember.RSVP.hash({
facebookFeedObjects: this.get('store').query('facebook-feed', {
fields: 'id,type,message,from,comments',
access_token: '1333570303337296%7CssnHtq9p3DuFAxX23XRx7Dc1reQ'
})
});
}
});/app/adapters/facebook-feed.js:
import Ember from 'ember';
import DS from 'ember-data';
export default DS.JSONAPIAdapter.extend({
host: 'https://graph.facebook.com/v2.7',
namespace: '604231966385537',
pathForType: function(type) {
return 'feed';
}
});/app/models/facebook-photo.js:
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
import { belongsTo, hasMany } from 'ember-data/relationships';
export default Model.extend({
message: attr(),
comments: hasMany('facebook-comment', { polymorphic: true })
});/app/serializers/facebook-feed.js:
import DS from 'ember-data';
export default DS.JSONAPISerializer.extend({
modelNameFromPayloadKey(key) {
let withPrefix = 'facebook-' + key;
return this._super(withPrefix);
},
payloadKeyFromModelName(modelName) {
let type = this._super(modelName);
return `${type.replace('facebook-', '')}`;
}
});/app/serializers/facebook-photo.js:
import DS from 'ember-data';
export default DS.JSONSerializer.extend(DS.EmbeddedRecordsMixin, {
modelNameFromPayloadKey(key) {
let withPrefix = 'facebook-' + key;
return this._super(withPrefix);
},
payloadKeyFromModelName(modelName) {
let type = this._super(modelName);
return `${type.replace('facebook-', '')}`;
},
attrs: {
comments: { embedded: 'always' }
}
});/app/templates/index.hbs:
<h3>Facebook</h3>
<ul>
{{#each model.facebookFeedObjects as |obj|}}
<li>
<h4>{{obj.message}}</h4>
<ul>
{{#each obj.comments as |comment|}}
<li>{{comment}}</li>
{{/each}}
</ul>
</li>
{{/each}}
</ul>发布于 2016-09-01 17:25:27
我认为你最好的选择是写你的自己的自定义序列化程序。与此类似的是:
export default DS.JSONAPISerializer.extend({
serialize(snapshot, options) {
var json = this._super(...arguments);
json.data.attributes.message = json.data.message;
json.data.attributes.from = {
name: json.data.from.name,
id: json.data.from.id
}
delete json.data.message;
delete json.data.from
return json;
},
});请注意,这没有考虑到comments字段,但是您应该能够做一些类似的事情来构建关系以坚持JSON API格式。
https://stackoverflow.com/questions/39273350
复制相似问题