2012-09-22 13 views
14

के साथ एकवचन संसाधनों को कैसे संभाला जाए एम्बर-डेटा में एकवचन संसाधन कैसे प्रबंधित किए जाते हैं? मैं निम्नलिखित RESTful मार्गों है कहते हैं:RESTAdapter

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

एंबर-डेटा find() उम्मीद एक सरणी वापस जाने के लिए, के साथ साथ यह स्वचालित रूप से किसी भी यूआरएल मैं अपने मॉडल को पारित pluralize की कोशिश करता है। इस स्थिति को संभालने का सबसे अच्छा तरीका क्या है?

उत्तर

7

ऐसी कई चीजें हैं जो आप यहां कर सकते हैं।

RESTAdapter कॉल बहुवचन कहते हैं, जो या तो नाम के अंत में "एस" जोड़ता है, या यदि यह मौजूद है तो बहुवचन हैश में नाम दिखता है। मान लें कि आपका डीएस। मॉडल 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" 
    }) 
}); 
+0

buildURL फ़ंक्शन को ओवरराइड करना सभी मॉडलों पर लागू होगा, हालांकि, सही? मेरे गैर-एकवचन मॉडल के बारे में क्या? इसके अलावा, भले ही मैं बहुवचन बदलूं, 'ढूंढें() '(तर्क के बिना) वस्तुओं की एक सरणी की अपेक्षा करता है, ताकि यह काम न करे। और यदि मैं खोजने के लिए एक नकली आईडी पास करता हूं, तो मुझे केवल एक आईडी तर्क ('/ cart /: fake_id') को स्वीकार करने के लिए अपने सर्वर मार्गों को संशोधित करना होगा। यह कुछ सामान्य और सरल के लिए बहुत हैकी लगता है। –

+0

बिल्ड यूआरएल ऐसा कुछ कर सकता है: '' if (record.get ('singularResouce') {...} else {this._super.apply (यह, तर्क);} ''। (...) कर सकते हैं अपना खुद का एकवचन निर्माण यूआरएल फ़ंक्शन बनें, और आपके एकवचन मॉडल में 'DS.Model.extend ({singularResouce: true})' ' – Ryan

+0

होगा, आप फिर से' 'buildUrl'' कॉल जैसे कुछ स्नैज़ी भी कर सकते हैं, लेकिन पास आईडी के रूप में अपरिभाषित। – Ryan

3

तो, मैं GitHub पर this pull request पाया। यह 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 मणि का प्रयोग करके):

attributes :id 
def id 
    "singleton" 
end 

यह आवश्यक है, क्योंकि, जाहिरा तौर पर, अगर जेसन प्रतिक्रिया में आईडी इस मामले में खोजने() (singleton) से अनुरोधित आईडी से मेल नहीं खाती है, तो एम्बर मॉडल में डेटा लोड नहीं करेगा।

अब, यह स्पष्ट रूप से आदर्श समाधान नहीं है, लेकिन जब तक एम्बर-डेटा इसके लिए समर्थन जोड़ता है, ऐसा लगता है कि यह जाने के लिए कम से कम दर्दनाक तरीका है।

वैसे, मैंने समर्थन जोड़ने के लिए an issue दायर किया।

+0

मैंने इस समाधान को कार्यान्वित करने का प्रयास किया और यह प्रारंभिक लोड पर काम करता है ... लेकिन एक बार जब मैं किसी अन्य टैब पर जाता हूं और फिर एकवचन संसाधन टैब पर वापस जाता हूं, तो एपी एंडपॉइंट को फिर से कॉल नहीं किया जाता है। कोई विचार? – flynfish

2

यहां यह है कि मुझे यह एम्बर 1.9 में कैसे काम मिला। सबसे पहले मैंने गाइड के this section पढ़ा। बहुत नीचे यह बताता है कि केवल एक मॉडल के लिए एडाप्टर को ओवरराइड कैसे करें।

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

pathForType समारोह जहां pluralization होता है (कम से कम RESTAdapter जो मैं उपयोग कर रहा हूँ में) ताकि एडाप्टर के अन्य कार्यक्षमता से कोई भी प्रभावित हो जाता है (होस्ट, या नाम स्थान की तरह) है।

1

बस मेरे लिए काम कर रहे एक और पूर्ण समाधान को साझा करने के लिए - अपने ऐप के एप्लिकेशन राउटर का विस्तार करें (जो स्वयं DS.RESTAdapter को बढ़ाता है)।

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

अगला, App.Router में अपना संसाधन परिभाषित करें।मानचित्र:

this.resource('cart'); 

अंत में, अपने मार्ग में आईडी के रूप में एक खाली स्ट्रिंग पास करें। यह आईडी के बिना यूआरएल उत्पन्न होने की अनुमति देता है।

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