Как обрабатывать особые ресурсы с помощью RESTAdapter
Как особые ресурсы обрабатываются в данных ember? Скажем, у меня есть следующие маршруты RESTful:
GET /cart
POST /cart
UPDATE /cart
DELETE /cart
ember-data ожидает, что find()
вернет массив, плюс он автоматически попытается плюрализовать любой url, который я передаю своей модели. Каков наилучший способ справиться с этой ситуацией?
Ответы
Ответ 1
Здесь вы можете сделать несколько вещей.
RESTAdapter
вызывает плюрализацию, которая либо добавляет "s" в конец имени, либо ищет имя в многоэлементном хеше, если оно существует. Предполагая, что ваш DS.Model App.Cart
.
https://github.com/emberjs/data/blob/master/packages/ember-data/lib/adapters/rest_adapter.js#L209
DS.RESTAdapter.create({
plurals: {
cart: 'cart'
}
});
Если ваша схема URL очень отличается и требует некоторой дополнительной логики, вы можете фактически переопределить функцию buildURL.
https://github.com/emberjs/data/blob/master/packages/ember-data/lib/adapters/rest_adapter.js#L288
DS.RestAdapter.create({
buildURL: function() {
return "/always_this"
})
});
Ответ 2
Итак, я нашел этот запрос на перенос на github. Это 8 месяцев, поэтому с тех пор не будет работать из-за дополнительной сложности, но я применил обходное решение, предлагаемое так:
App.store = DS.Store.create({
revision: 4,
adapter: DS.RESTAdapter.create({
plurals: {
'cart': 'cart'
}
})
});
App.Cart.reopenClass({
find: function () {
this._super("singleton");
}
});
На моем сервере (я использую рельсы), мне нужно добавить следующие маршруты к моим маршрутам:
get "cart/:ignored" => "carts#show"
Затем я должен добавить следующее в CartSerializer
(используя active_model_serializers gem):
attributes :id
def id
"singleton"
end
Это необходимо, поскольку, по-видимому, если идентификатор в json-ответе не соответствует идентификатору, запрошенному в find() (singleton
в этом случае), то ember не будет загружать данные в модель.
Теперь это, очевидно, не идеальное решение, но пока данные ember-data не поддерживают его, это кажется наименее болезненным способом.
Кстати, я добавил проблему, чтобы добавить поддержку.
Ответ 3
Вот как я работал в Ember 1.9. Сначала я прочитал этот раздел руководства. В самом низу он объясняет, как переопределить адаптер только для одной модели.
App.CartAdapter = App.ApplicationAdapter.extend {
pathForType: ->
'cart'
}
Функция pathForType - это то место, где происходит множественность (по крайней мере, в RESTAdapter, который я использую), поэтому ни одна из других функций адаптера не пострадает (например, хост или пространство имен).
Ответ 4
Просто для того, чтобы предоставить более полное решение, которое работает для меня - расширьте приложение ApplicationRouter (которое само по себе расширяет DS.RESTAdapter).
App.CartAdapter = App.ApplicationAdapter.extend({
pathForType: function(type) {
return 'cart';
}
});
Затем определите свой ресурс в App.Router.map:
this.resource('cart');
Наконец, передайте пустую строку в качестве идентификатора вашего маршрута. Это позволяет генерировать URL без идентификатора.
App.CartRoute = Ember.Route.extend({
model : function(params) {
return this.store.find('cart', '');
}
});