12

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

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

它使用以下非常标准的 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

这一切都使用标准的 Store/Adapter 映射到 Ember-Data。

但是,假设为了“加星”或“取消星”一个人,API 不允许我们通过标准更新操作来执行此操作。此操作有一个特定的 API 端点:

POST   /people/id/star   - mark a person as "starred"
POST   /people/id/unstar - mark a person as "unstarred"

如何将此 API 与 Ember 数据相匹配?

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

请注意,我无法控制 API,因此我无法POST /people/id意识到“星标”,以便它适合标准更新。

4

5 回答 5

10

有一段时间了,当时可能还做不到,但是你可以直接调用你的适配器的ajax方法:

YourApp.Store.prototype.adapter.ajax(url, action, {data: hashOfParams})

例如:

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

对于您的问题:

YourApp.Store.prototype.adapter.ajax('/people' + id + '/star','POST')

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

url = YourApp.Store.prototype.adapter.buildURL('people',id) + '/star'

编辑 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

并这样称呼它-

@customAjax('PUT', 'modelClass', modelId, 'nonCRUDActionName', optionalHashOfAdditionalData).then (response) =>
  #do something with response
于 2014-04-13T18:04:38.143 回答
2

我遇到了同样的问题,并使用此处解释的修改版本解决了它: Ember.js 中的非粗略导轨操作

基本上,您需要使用 Jquery AJAX 调用,对我来说重要的部分是更改 contentType 以获取要在请求标头中发送的身份验证数据,而不是在表单数据中(默认情况下,如果您包含数据在您的电话中)。此外,请确保在 AJAX 部分中提供正确的上下文,否则 'this' 在 'success' 回调中将不起作用:

App.ItemController = Ember.ObjectController.extend
    actions:
        starItem: ->
            controller = this
            item = @get 'model'
            id = item.id
            token = @auth.get 'authToken'
            $.ajax
                type: 'PUT'
                context: controller
                data: '{ "auth_token": "' + token + '"}'
                url: '/api/v1/items/' + id + '/star'
                contentType: 'application/json; charset=UTF-8'
                dataType: 'json'
                success: ->
                    if @get 'item.starred_by_user'
                        @set 'model.starred_by_user', false
                        item.decrementProperty('total_stars') 
                    else 
                        @set 'model.starred_by_user', true
                        item.incrementProperty('total_stars')
于 2014-03-25T09:42:58.377 回答
0

我认为,在CQRS中,星号和取消星号是命令。所以你应该声明模型 PersonStar 并使用它。

于 2013-03-15T04:20:19.790 回答
0

也许是一个好的开始:https ://github.com/beautifulnode/ember.request

还没有尝试过,但在你的情况下似乎很有希望......

于 2012-03-14T16:40:40.407 回答
-1

在讨论组中,耶胡达提到这还不可能。

于 2012-03-18T01:15:15.113 回答