使用余烬数据的非CRUD操作

rli*_*sey 12 javascript ember.js ember-data

假设我有以下ember-data模型:

App.Person = DS.Model.extend({
    firstName: DS.attr('string'),
    lastName:  DS.attr('string'),
    starred:   DS.attr('boolean')
});
Run Code Online (Sandbox Code Playgroud)

这与使用以下非常标准的CRUD API的Rails应用程序通信:

GET    /people    - get a list of people
POST   /people    - create a new person
GET    /people/id - get a specific person
PUT    /people/id - update a specific person
DELETE /people/id - delete a specific person
Run Code Online (Sandbox Code Playgroud)

这些都使用标准存储/适配器映射到Ember-Data.

但是,让我们说,为了让一个人"明星化"或"解除明星化",API不允许我们通过标准更新操作来执行此操作.此操作有一个特定的API端点:

POST   /people/id/star   - mark a person as "starred"
POST   /people/id/unstar - mark a person as "unstarred"
Run Code Online (Sandbox Code Playgroud)

如何在Ember Data中使用此API?

看起来我需要以某种方式扩展DS.Store和DS.RESTAdapter,但我不确定让他们了解这些不同操作的最佳方法.对于应用程序的通用适配器必须知道主演人员,也感觉有点不对劲.

请注意,我无法控制API,因此我无法POST /people/id了解"主演",因此它适合标准更新.

and*_*rov 10

有一段时间,当时可能无法实现,但您可以直接调用适配器的ajax方法:

YourApp.Store.prototype.adapter.ajax(url, action, {data: hashOfParams})
Run Code Online (Sandbox Code Playgroud)

例如:

YourApp.Store.prototype.adapter.ajax('/products', 'GET', {data: {ids: [1,2,3]}})
Run Code Online (Sandbox Code Playgroud)

对于你的问题:

YourApp.Store.prototype.adapter.ajax('/people' + id + '/star','POST')
Run Code Online (Sandbox Code Playgroud)

编辑 - 使用buildURL非常有用,特别是如果您在适配器上设置了命名空间:

url = YourApp.Store.prototype.adapter.buildURL('people',id) + '/star'
Run Code Online (Sandbox Code Playgroud)

编辑2 - 您也可以使用适配器container.lookup('adapter:application'),如果您没有应用程序的全局访问权限(例如ES6模块/ ember-cli),这非常有用

编辑3 - 以上是指Ember/Ember-CLI的过时版本.现在我在mixin中定义这个函数 -

  customAjax: (method, type, id, action, hash = null) ->
    #note that you can now also get the adapter from the store -
    #adapter = @store.adapterFor('application')
    adapter = @container.lookup('adapter:application')
    url = adapter.buildURL(type, id) + '/' + action
    hash['data'] = $.extend({}, hash) if hash #because rails
    adapter.ajax(url, method, hash).then (result) =>
      return result
Run Code Online (Sandbox Code Playgroud)

并称之为 -

@customAjax('PUT', 'modelClass', modelId, 'nonCRUDActionName', optionalHashOfAdditionalData).then (response) =>
  #do something with response
Run Code Online (Sandbox Code Playgroud)


小智 -1

在讨论组中,Yehuda 提到这还不可能。