Ответ 1
В дискуссионной группе Иегуда отметил, что это пока невозможно.
Скажем, у меня есть следующая модель данных ember-data:
App.Person = DS.Model.extend({
firstName: DS.attr('string'),
lastName: DS.attr('string'),
starred: DS.attr('boolean')
});
Это связано с приложением Rails со следующим довольно стандартным API CRUD:
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
Все это сопоставляется с Ember-Data со стандартным Store/Adapter.
Однако скажем, что для того, чтобы "звезда" или "неустановить" человека, API не позволяет нам делать это с помощью стандартного действия по обновлению. Для этого действия существует конкретная конечная точка API:
POST /people/id/star - mark a person as "starred"
POST /people/id/unstar - mark a person as "unstarred"
Как мне сопоставить этот API с Ember Data?
Похоже, мне нужно каким-то образом расширить DS.Store и DS.RESTAdapter, но я не уверен в лучшем подходе, чтобы информировать их об этих разных действиях. Он также чувствует себя немного не так, что общий адаптер для приложения должен знать о главных героях.
Обратите внимание, что я не имею никакого контроля над API, поэтому я не могу сделать POST /people/id
осведомленным о "главной роли", чтобы он соответствовал стандартным обновлениям.
В дискуссионной группе Иегуда отметил, что это пока невозможно.
Некоторое время, возможно, это было невозможно в то время, но вы можете напрямую вызвать метод 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')
, что полезно, если у вас нет глобального доступа к приложению (ex ES6 modules/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
Я прошел ту же проблему и решил ее, используя измененную версию того, что объясняется здесь: Действия без crud rails в 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')
Может быть, хорошее начало: https://github.com/beautifulnode/ember.request
Не пробовал еще, но кажется вам многообещающим в вашем случае...
Я думаю, что в CQRS therms star и notar являются командами. Поэтому вы должны объявить модель PersonStar и работать с ней.