23

我正在使用 Ember-Data Rest-Adapter,从我的服务器返回的 JSON 看起来基本上像Active Model Serializers 文档中的那个

{
  "meta": { "total": 10 },
  "posts": [
    { "title": "Post 1", "body": "Hello!" },
    { "title": "Post 2", "body": "Goodbye!" }
  ]
}

从服务器获取数据是可行的,但不幸的是我无法弄清楚我可以从我的 JSON 响应中访问元信息的位置。

根据我对 ember-data 的 github issue 的研究,对元信息的支持似乎是通过 commit 1787bff实现的。

但即使有测试用例,我也无法弄清楚如何访问元信息。

App.PostController = Ember.ArrayController.extend({
   ....
   requestSearchData: function(searchParams){
      posts = App.Post.find(searchParams);
      this.set('content', posts);
      // don't know how to access meta["total"]
      // but I want to do something like this:
      // this.set('totalCount', meta["total"])
   }
})

你们中的任何人都可以为我解释一下吗?我知道 Ember api 正在快速发展,但我确信我只是遗漏了一小部分,这实际上是可能的。

4

3 回答 3

7

我找到了一种更简洁的方法,可以使用 ember-data 从服务器响应中提取元信息。

我们必须告诉序列化程序期望哪些元信息(在这种情况下是分页):

 App.serializer = DS.RESTSerializer.create();

 App.serializer.configure({ pagination: 'pagination' });

 App.CustomAdapter = DS.RESTAdapter.extend({
   serializer: App.serializer
 });

 App.Store = DS.Store.extend({
   adapter: 'App.CustomAdapter'
 });

之后,每次服务器发送带有分页对象的元属性时,该对象都会被添加到所TypeMaps请求模型类的存储属性中。

例如以下响应:

  {
    'meta': {'pagination': { 'page': 1, 'total': 10 } },
    'posts':[
      ...
    ]
  }

App.Post TypeMap-Model 将在帖子加载后包含分页对象。

您无法直接观察商店的 TypeMaps 属性,因此我向 PostsController 添加了一个计算属性以访问请求分页元信息:

 App.PostsController = Ember.ArrayController.extend({
    pagination: function () {
      if (this.get('model.isLoaded')) {
        modelType = this.get('model.type');
        this.get('store').typeMapFor(modelType).metadata.pagination
      }
    }.property('model.isLoaded')
 });

我真的不认为这是解决元信息问题的好方法,但这是我能够用 Ember-Data 提出的最佳解决方案。也许这在未来会更容易。

于 2013-08-15T10:03:34.813 回答
6

我想出了一种访问响应中传递的元信息的方法。但不幸的是,开箱即用的 ember-data 似乎并不支持它,我正在将元信息写入一个全局变量,然后通过请求控制器中的绑定访问该变量。

我最终自定义了 RESTAdapter 正在使用的序列化程序:

App.CustomRESTSerializer = DS.RESTSerializer.extend({
  extractMeta: function(loader, type, json) {
    var meta;
    meta = json[this.configOption(type, 'meta')];
    if (!meta) { return; }
    Ember.set('App.metaDataForLastRequest', meta);
    this._super(loader, type, json);
  }
});

App.Store = DS.Store.extend({
  revision: 11,
  adapter: DS.RESTAdapter.create({
    bulkCommit: false,
    serializer: App.CustomRESTSerializer
  })
});

我知道这不是特别漂亮,实际上认为这与 ember-data 期望我们做的事情背道而驰,但目前它工作正常。

我将尝试以更好的方式使用 ember-data 并在它工作时提交一个拉取请求,或者当其他人有兴趣让它工作时在 github 上打开一个问题。

如果有人找到更干净的解决方案,请告诉我。

于 2013-01-16T11:31:33.297 回答
2

我认为您的直接解决方法是将 totalCount 附加到您的模型(recordArray),请参阅此线程

另一种方法是创建自己的适配器:

DS.Adapter.create({
  find: function (store, type, id) {
    $.ajax({
      url:      type.url,
      dataType: 'jsonp',
      context:  store,
      success:  function(response){
        this.load(type, id, response.data);
      }
    });
  },
  findAll: function(store, type) {
    $.ajax({
      url:      type.url,
      dataType: 'jsonp',
      context:  store,
      success:  function(response){
        this.loadMany(type, response.data);
      }
    });
  }
});

findAll 方法中成功回调的响应参数,应该是你需要的对象:

response: {
  meta: {
    totalCount: 10
  },
  posts: [{}, {}]
}

希望这可以帮助。

于 2013-02-16T15:50:00.400 回答