2012-09-22 20 views
14

W jaki sposób obsługiwane są pojedyncze zasoby w danych ember? Że mam następujących trasach relaksującego:Jak obsługiwać pojedyncze zasoby za pomocą RESTAdapter

GET /cart 
POST /cart 
UPDATE /cart 
DELETE /cart 

Ember-data spodziewa find() zwracać tablicę, plus to automatycznie próbuje pluralize dowolnego adresu URL przechodzę do mojego modelu. Jaki jest najlepszy sposób poradzenia sobie z tą sytuacją?

Odpowiedz

7

Jest wiele rzeczy, które możesz zrobić tutaj.

Wywołania liczby mnogiej, która dodaje "s" na końcu nazwy lub wyszukuje nazwę w mieszaniu w liczbie mnogiej, jeśli istnieje. Zakładając, że twój DS.Model jest App.Cart.

https://github.com/emberjs/data/blob/master/packages/ember-data/lib/adapters/rest_adapter.js#L209

DS.RESTAdapter.create({ 
    plurals: { 
    cart: 'cart' 
    } 
}); 

Jeśli schemat URL jest bardzo różna i wymaga dalszych logikę, rzeczywiście można zastąpić funkcję 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" 
    }) 
}); 
+0

Zastępowanie funkcji buildURL będzie miało zastosowanie do wszystkich modeli, prawda? A co z moimi nietypowymi modelami? Ponadto, nawet jeśli zmienię liczbę mnogą, 'find()' (bez argumentów) oczekuje tablicy obiektów, więc to nie zadziała. I jeśli przekażę fałszywy identyfikator do znalezienia, to muszę zmodyfikować moje trasy serwera, aby zaakceptować argument id ('/ cart /: fake_id') tylko po to, aby całkowicie go zignorować. Wydaje się po prostu zbyt zjadliwe na coś tak powszechnego i prostego. –

+0

URL kompilacji może zrobić coś takiego: '' if (record.get ('singularResouce') {...} else {this._super.apply (this, arguments);} ''. (...) może być twoją osobliwą funkcją budowania adresu URL, a twoje pojedyncze modele będą miały '' DS.Model.extend ({singularResouce: true}) ''. – Ryan

+0

Możesz nawet zrobić coś snazzy, jak wywołanie '' buildUrl'', ale przekazać undefined jako id. – Ryan

3

Więc znalazłem this pull request na github. To 8 miesięcy, więc nie będzie działać z powodu dodanego złożoność od tego czasu, ale już wdrożone obejście zaproponował tak:

App.store = DS.Store.create({ 
    revision: 4, 
    adapter: DS.RESTAdapter.create({ 
    plurals: { 
     'cart': 'cart' 
    } 
    }) 
}); 

App.Cart.reopenClass({ 
    find: function() { 
    this._super("singleton"); 
    } 
}); 

na mój serwer (używam szyn), muszę dodać następujące moich trasach:

get "cart/:ignored" => "carts#show" 

Wtedy muszę dodać następujące CartSerializer (używając active_model_serializers gem):

attributes :id 
def id 
    "singleton" 
end 

jest to konieczne, ponieważ, jak widać, jeśli id w odpowiedzi json nie pasuje do ID żądanego z find() (singleton w tym przypadku), wtedy ember nie załaduje danych do modelu.

To oczywiście nie jest idealne rozwiązanie, ale dopóki dane ember nie dodadzą mu wsparcia, wydaje się, że to najmniej bolesna droga.

Przy okazji złożyłem an issue, aby dodać obsługę.

+0

Próbowałem zaimplementować to rozwiązanie i działa ono przy początkowym ładowaniu ... ale po przejściu do innej karty, a następnie z powrotem do zakładki z osobliwym zasobem, punkt końcowy interfejsu API nie zostanie ponownie wywołany. Jakieś pomysły? – flynfish

2

Oto, jak to działa w Ember 1.9. Najpierw przeczytałem this section przewodnika. Na samym dole wyjaśnia, w jaki sposób zastąpić adapter dla tylko jednego modelu.

funkcja
App.CartAdapter = App.ApplicationAdapter.extend { 
    pathForType: -> 
    'cart' 
} 

pathForType gdzie jest pluralizacji zdarza (przynajmniej w RESTAdapter których używam), więc żaden z innych funkcjonalności adaptera dostaje wpływ (jak gospodarz, lub nazw).

1

Wystarczy udostępnić bardziej kompletne rozwiązanie, które działa dla mnie - rozszerzyć aplikację ApplicationRouter (która sama rozszerza DS.RESTAdapter).

App.CartAdapter = App.ApplicationAdapter.extend({ 
    pathForType: function(type) { 
     return 'cart'; 
    } 
}); 

Następnie zdefiniuj swój zasób w App.Router.mapa:

this.resource('cart'); 

Na koniec przekazujemy pusty ciąg jako identyfikator na trasie. To pozwala na generowanie adresu URL bez identyfikatora.

App.CartRoute = Ember.Route.extend({ 
    model : function(params) { 
     return this.store.find('cart', ''); 
    } 
}); 
Powiązane problemy