Ember Data返回结构化JSON

时间:2013-02-01 11:54:10

标签: ember.js ember-data

我已经和Ember Data合作了一段时间,而且我对它很满意。我喜欢它强迫我以合理的方式构建我的REST api的方式。

我遇到了一些问题,其中一个问题是:我之前使用的是一个扁平结构的模型:

App.Pageview = DS.Model.extend({
  event: attr('string'),
  value: attr('string'),
  time: attr('date'),
  count: attr('number')
});

在这种情况下,值是一个字符串中的url。这个模型适用于JSON,如下所示:

{
  "event" : "pageview",
  "value" : "google.com/some/page",
  "time" : "2013-01-31T16:30:00.000Z",
  "count" : 14
}

我已经改变了JSON在数据库中的结构方式,以便于查询,所以现在它看起来像这样:

{
  "event" : "pageview",
  "value" : {
    "url" : "google.com/some/page",
    "domain" : "google.com",
    "path" : "/some/page"
  },
  "time" : "2013-01-31T16:30:00.000Z",
  "count" : 14
}

但是现在我真的不知道去哪儿了。我尝试过这样的事情:

App.Pageview = DS.Model.extend({
  event: attr('string'),
  value: {
      domain: attr('string'),
      url: attr('string'),
      path: attr('string')
  },
  time: attr('date'),
  count: attr('number')
});

但这似乎不起作用,我测试了它:

  console.log(item.get('value'));
  console.log(item.get('value.domain'));
  // console.log(item.get('value').get('domain')); // throws 
  console.log(item.get('value').domain);

得到以下结果:http://d.pr/i/izDD

所以我做了一些挖掘,发现我应该做这样的事情:

App.Pageview = DS.Model.extend({
  event: attr('string'),
  value: DS.belongsTo('App.SplitUrl', {embedded:true}),
  time: attr('date'),
  count: attr('number')
});

App.SplitUrl = DS.Model.extend({
  domain: attr('string'),
  url: attr('string'),
  path: attr('string')
});

但由于我得到错误,这不起作用:

Uncaught TypeError: Cannot call method 'hasOwnProperty' of undefined 

当我在没有id的REST api中发送一个对象时,通常会发生这种情况。以下是我的REST api的确切响应:

http://d.pr/n/UyW0

注意:我已经重载了适配器,因此它希望id位于_id字段中,以便使用mongodb可以更好/更轻松地工作。这就是我重载适配器的方式:

App.Store = DS.Store.extend({
  revision: 11,
  adapter: DS.RESTAdapter.create({
    serializer: DS.JSONSerializer.extend({
      primaryKey: function(type) {
        return '_id';
      }
    }), 
    namespace: 'api'
  })
});

任何人都可以帮我解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

假设您正在使用ember-data revision 11,请尝试将您的值配置为嵌入在适配器中。

DS.RESTAdapter.map('App.SplitUrl',{value:{ embedded:'always'}});