दिलचस्प पोस्ट
सीएसएस फ्लेक्सबॉक्स में, क्यों नहीं "जज-वस्तुएं" और "औचित्य-स्व" गुण हैं? जावा अपने 16-बिट वर्ण प्रकार में UTF-16 अक्षरों को कैसे संग्रहीत करता है? कैसे एक वस्तु में आंतरिक वस्तुओं / संपत्ति पर पुनरावृत्त करने के लिए उद्देश्य-सी में शून्य बनाम शून्य सी ++ में परमाणु के एक वेक्टर को कैसे घोषित करना बहुआयामी आकार सीएफएलएफ के साथ एलएफ़ की जगह जीआईटी Php में एन एरेज़ के समन्वित मूल्य एसक्यूएल केस स्टेटमेंट सिंटैक्स? एक सरल पाठ फ़ाइल पढ़ना सी # में बयान का उपयोग कर नेस्टेड आईओएस एईएस एन्क्रिप्शन – एनक्रिप्ट करने में विफल Php स्क्रिप्ट के दोहरे उद्धरण गूंज IOS UIViewController जीवन चक्र को समझने के लिए देख रहे हैं एमपी 3 प्लेबैक की शुरुआत में मीडियाप्लेयर स्टुटर्स

एम्बरजेएस / एम्बर डेटा में एक ही रूट के साथ कई मॉडल का उपयोग कैसे करें?

डॉक्स पढ़ने से, ऐसा लगता है कि आपको ऐसा मार्ग करने के लिए एक मॉडल असाइन करना होगा (या चाहिए):

App.PostRoute = Ember.Route.extend({ model: function() { return App.Post.find(); } }); 

अगर मुझे एक निश्चित मार्ग में कई वस्तुओं का उपयोग करने की आवश्यकता हो तो क्या होगा? यानी डाक, टिप्पणियाँ और उपयोगकर्ता? मैं उन मार्गों को लोड करने के लिए कैसे बताऊं?

Solutions Collecting From Web of "एम्बरजेएस / एम्बर डेटा में एक ही रूट के साथ कई मॉडल का उपयोग कैसे करें?"

अंतिम अद्यतन हमेशा के लिए : मैं इसे अद्यतन नहीं रख सकता। तो यह नापसंद है और संभवतः इस तरह से होगा। यहां एक बेहतर, और अधिक अद्यतित थ्रेड EmberJS है: एक ही रूट पर कई मॉडल कैसे लोड करें?

अद्यतन: मेरे मूल उत्तर में मैंने embedded: true उपयोग करने के लिए कहा embedded: true मॉडल परिभाषा में embedded: true । यह गलत है संशोधन 12 में, एम्बर-डेटा को उम्मीद है कि संग्रह के लिए एकल रिकॉर्ड या _ids लिए एक प्रत्यय ( लिंक ) _ids के साथ परिभाषित किया जाने वाला विदेशी कुंजी। निम्नलिखित के समान कुछ:

 { id: 1, title: 'string', body: 'string string string string...', author_id: 1, comment_ids: [1, 2, 3, 6], tag_ids: [3,4] } 

मैंने बेला को अपडेट किया है और अगर कोई बदलाव करता है या अगर मुझे इस जवाब में दिए गए कोड के साथ और अधिक समस्याएं मिलें तो फिर से ऐसा करेंगे।


संबंधित मॉडल के साथ उत्तर दें:

जिस परिदृश्य का आप वर्णन कर रहे हैं, मैं मॉडल के बीच एसोसिएशनों ( embedded: true ) पर भरोसा करता हूं और इस मार्ग में Post मॉडल को लोड करता हूं, इस पर विचार करने के लिए कि मैं DS.hasMany एसोसिएशन को Comment मॉडल और DS.belongsTo एसोसिएशन के लिए परिभाषित कर सकता हूं। Comment और Post मॉडल दोनों में User । कुछ इस तरह:

 App.User = DS.Model.extend({ firstName: DS.attr('string'), lastName: DS.attr('string'), email: DS.attr('string'), posts: DS.hasMany('App.Post'), comments: DS.hasMany('App.Comment') }); App.Post = DS.Model.extend({ title: DS.attr('string'), body: DS.attr('string'), author: DS.belongsTo('App.User'), comments: DS.hasMany('App.Comment') }); App.Comment = DS.Model.extend({ body: DS.attr('string'), post: DS.belongsTo('App.Post'), author: DS.belongsTo('App.User') }); 

यह परिभाषा निम्नलिखित की तरह कुछ उत्पन्न करेगी:

मॉडल के बीच एसोसिएशन

इस परिभाषा के साथ, जब भी मुझे कोई पद find , उस पद से जुड़े टिप्पणियों के संग्रह का उपयोग मेरे पास होगा, और इस टिप्पणी के लेखक के रूप में भी और उपयोगकर्ता जो पद के लेखक हैं, क्योंकि वे सभी एम्बेडेड हैं । मार्ग सरल रहता है:

 App.PostsPostRoute = Em.Route.extend({ model: function(params) { return App.Post.find(params.post_id); } }); 

तो PostRoute (या PostsPostRoute यदि आप resource का उपयोग कर रहे हैं तो), मेरे टेम्पलेट में नियंत्रक की content तक पहुंच होगी, जो Post मॉडल है, इसलिए मैं लेखक को संदर्भित कर सकता हूं, बस author रूप में

 <script type="text/x-handlebars" data-template-name="posts/post"> <h3>{{title}}</h3> <div>by {{author.fullName}}</div><hr /> <div> {{body}} </div> {{partial comments}} </script> <script type="text/x-handlebars" data-template-name="_comments"> <h5>Comments</h5> {{#each content.comments}} <hr /> <span> {{this.body}}<br /> <small>by {{this.author.fullName}}</small> </span> {{/each}} </script> 

( बेला देखें)


गैर-संबंधित मॉडलों के साथ उत्तर दें:

हालांकि, यदि आपका परिदृश्य आपके द्वारा वर्णित, और / या किसी खास रूट के लिए (या क्वेरी) अलग मॉडल का उपयोग करने के लिए थोड़ा अधिक जटिल है, तो मैं Route#setupController में यह करने की सिफारिश करेगा Route#setupController उदाहरण के लिए:

 App.PostsPostRoute = Em.Route.extend({ model: function(params) { return App.Post.find(params.post_id); }, // in this sample, "model" is an instance of "Post" // coming from the model hook above setupController: function(controller, model) { controller.set('content', model); // the "user_id" parameter can come from a global variable for example // or you can implement in another way. This is generally where you // setup your controller properties and models, or even other models // that can be used in your route's template controller.set('user', App.User.find(window.user_id)); } }); 

और अब जब मैं पोस्ट मार्ग में हूं, तो मेरे टेम्पलेट्स को नियंत्रक में user संपत्ति तक पहुंच user होगी क्योंकि यह सेटअप setupController हुक में स्थापित किया गया था:

 <script type="text/x-handlebars" data-template-name="posts/post"> <h3>{{title}}</h3> <div>by {{controller.user.fullName}}</div><hr /> <div> {{body}} </div> {{partial comments}} </script> <script type="text/x-handlebars" data-template-name="_comments"> <h5>Comments</h5> {{#each content.comments}} <hr /> <span> {{this.body}}<br /> <small>by {{this.author.fullName}}</small> </span> {{/each}} </script> 

( बेला देखें)

Em.Object का उपयोग करना। कई मॉडल को समाहित करने के उद्देश्य model हुक में सभी डेटा प्राप्त करने का एक अच्छा तरीका है लेकिन यह सुनिश्चित नहीं कर सकता कि सभी डेटा दृश्य प्रतिपादन के बाद तैयार किए गए हैं।

एक और विकल्प का उपयोग करना है Em.RSVP.hash यह कई वादों को एक साथ जोड़ती है और एक नया वादा वापस करता है नए वादा अगर सभी वादों के हल होने के बाद हल हो जाए और setupController को तब तक नहीं बुलाया जाता जब तक वादा हल हो या अस्वीकार नहीं किया जाता।

 App.PostRoute = Em.Route.extend({ model: function(params) { return Em.RSVP.hash({ post: // promise to get post comments: // promise to get comments, user: // promise to get user }); }, setupController: function(controller, model) { // You can use model.post to get post, etc // Since the model is a plain object you can just use setProperties controller.setProperties(model); } }); 

इस तरह से आपको सभी मॉडलों को देखने के पहले प्रस्तुति मिलती है। और Em.Object का उपयोग इस लाभ नहीं है।

एक और लाभ यह है कि आप वादा और गैर-वादे को जोड़ सकते हैं। इस कदर:

 Em.RSVP.hash({ post: // non-promise object user: // promise object }); 

Em.RSVP बारे में अधिक जानने के लिए इसे देखें : https://github.com/tildeio/rsvp.js


लेकिन यदि आपके मार्ग में गतिशील खंड हैं तो Em.RSVP Em.Object या Em.RSVP समाधान का उपयोग न करें

मुख्य समस्या link-to यदि आप यूआरएल को क्लिक-लिंक द्वारा link-to जरिए तैयार किया जाता है, तो मॉडल को सीधे उस मार्ग पर भेज दिया जाता है। इस मामले में model हुक को नहीं कहा जाता है और setupController में setupController आपको मॉडल link-to मिलता है link-to आपको देना।

एक उदाहरण ऐसा है:

मार्ग कोड:

 App.Router.map(function() { this.route('/post/:post_id'); }); App.PostRoute = Em.Route.extend({ model: function(params) { return Em.RSVP.hash({ post: App.Post.find(params.post_id), user: // use whatever to get user object }); }, setupController: function(controller, model) { // Guess what the model is in this case? console.log(model); } }); 

और link-to कोड, पोस्ट एक मॉडल है:

 {{#link-to "post" post}}Some post{{/link-to}} 

चीजें यहां दिलचस्प हो गई हैं जब आप पृष्ठ पर जाने के लिए url /post/1 का उपयोग करते हैं, model हुक कहलाता है, और setupController को सादा ऑब्जेक्ट मिलता है जब वादा का समाधान होता है।

लेकिन अगर आप link-to क्लिक करते हुए पृष्ठ पर जाते हैं, तो यह post मॉडल को post रूट से PostRoute और मार्ग model हुक की उपेक्षा करेगा इस मामले में setupController को post मॉडल मिलेगा, निश्चित तौर पर आप उपयोगकर्ता नहीं प्राप्त कर सकते हैं।

इसलिए सुनिश्चित करें कि आप गतिशील क्षेत्रों के साथ मार्गों में उनका उपयोग नहीं करते हैं।

थोड़ी देर के लिए मैं Em.RSVP.hash का उपयोग कर रहा था, लेकिन जो समस्या मैंने चली गई वह यह थी कि मैं अपने दृश्य का इंतजार नहीं करना चाहता था जब तक सभी मॉडलों को प्रतिपादन से पहले लोड किया गया। हालांकि, मुझे एक महान (लेकिन अपेक्षाकृत अनजान) समाधान मिल गया है, जो लोगों को नोवलिस में एम्बर का उपयोग करने के लिए शामिल है। प्रोमोइस प्रोक्सी मिक्सिन :

मान लें कि आपके पास एक ऐसा दृश्य है जिसमें तीन अलग-अलग दृश्य अनुभाग हैं। इन सभी वर्गों को अपने स्वयं के मॉडल द्वारा समर्थित किया जाना चाहिए। दृश्य के शीर्ष पर "स्प्लैश" सामग्री का समर्थन करने वाला मॉडल छोटा है और जल्दी से लोड हो जाएगा, ताकि आप उस सामान्य रूप से लोड कर सकते हैं:

मार्ग main-page.js :

 import Ember from 'ember'; export default Ember.Route.extend({ model: function() { return this.store.find('main-stuff'); } }); 

तब आप एक main-page.hbs Handlebars टेम्पलेट main-page.hbs बना सकते हैं:

 <h1>My awesome page!</h1> <ul> {{#each thing in model}} <li>{{thing.name}} is really cool.</li> {{/each}} </ul> <section> <h1>Reasons I Love Cheese</h1> </section> <section> <h1>Reasons I Hate Cheese</h1> </section> 

तो चलो अपने टेम्पलेट में कहते हैं कि आप अपने प्यार / पनीर के साथ नफरत संबंध के बारे में अलग-अलग वर्ग चाहते हैं, प्रत्येक (किसी कारण के लिए) अपने स्वयं के मॉडल द्वारा समर्थित प्रत्येक मॉडल से आपके पास प्रत्येक मॉडल से बहुत अधिक विवरण हैं, हालांकि आप जल्दी से रेंडर करने के लिए ऊपर की सामग्री चाहते हैं यह वह जगह है जहां {{render}} सहायक अंदर आ जाता है। आप अपने टेम्पलेट को इस प्रकार अपडेट कर सकते हैं:

 <h1>My awesome page!</h1> <ul> {{#each thing in model}} <li>{{thing.name}} is really cool.</li> {{/each}} </ul> <section> <h1>Reasons I Love Cheese</h1> {{render 'love-cheese'}} </section> <section> <h1>Reasons I Hate Cheese</h1> {{render 'hate-cheese'}} </section> 

अब आपको प्रत्येक के लिए नियंत्रकों और टेम्पलेट्स बनाने की आवश्यकता होगी चूंकि वे इस उदाहरण के लिए प्रभावी ढंग से समान हैं, इसलिए मैं सिर्फ एक का उपयोग करूँगा

love-cheese.js नामक नियंत्रक बनाएं:

 import Ember from 'ember'; export default Ember.ObjectController.extend(Ember.PromiseProxyMixin, { init: function() { this._super(); var promise = this.store.find('love-cheese'); if (promise) { return this.set('promise', promise); } } }); 

आप देखेंगे कि हम यहां PromiseProxyMixin का प्रयोग कर रहे हैं, जो नियंत्रक को वादा करता है- जागरूक है। जब नियंत्रक को आरम्भिक किया जाता है, तो हम यह संकेत देते हैं कि एम्बर डेटा के माध्यम से love-cheese मॉडल लोड होना चाहिए। आपको नियंत्रक के promise संपत्ति पर इस संपत्ति को सेट करना होगा।

अब, love-cheese.hbs नामक एक टेम्पलेट love-cheese.hbs :

 {{#if isPending}} <p>Loading...</p> {{else}} {{#each item in promise._result }} <p>{{item.reason}}</p> {{/each}} {{/if}} 

आपके टेम्पलेट में, आप वादा की स्थिति के आधार पर विभिन्न सामग्री को प्रस्तुत करने में सक्षम होंगे। जब आपका पेज शुरू में लोड होता है, तो आपके "कारण मीज़ पर्स" अनुभाग में प्रदर्शित होगा Loading... जब वादा लोड होता है, तो यह आपके मॉडल के प्रत्येक रिकॉर्ड के लिए जुड़े सभी कारणों को प्रस्तुत करेगा।

प्रत्येक अनुभाग स्वतंत्र रूप से लोड होगा और मुख्य सामग्री को तत्काल रेंडर करने से अवरुद्ध नहीं करेगा।

यह एक सरल उदाहरण है, लेकिन मुझे आशा है कि हर किसी को यह उतनी ही उपयोगी लगता है जितना मैंने किया था।

यदि आप सामग्री की कई पंक्तियों के समान कुछ करने की तलाश कर रहे हैं, तो आपको नोवीस के ऊपर और भी अधिक प्रासंगिक उदाहरण मिल सकते हैं यदि नहीं, तो ऊपर के लिए आपके लिए ठीक काम करना चाहिए।

यह सर्वोत्तम अभ्यास और भोले-भरे दृष्टिकोण नहीं हो सकता है, लेकिन यह अवधारणा से पता चलता है कि आप एक केंद्रीय मार्ग पर कितने मॉडल उपलब्ध कराएंगे:

 App.PostRoute = Ember.Route.extend({ model: function() { var multimodel = Ember.Object.create( { posts: App.Post.find(), comments: App.Comments.find(), whatever: App.WhatEver.find() }); return multiModel; }, setupController: function(controller, model) { // now you have here model.posts, model.comments, etc. // as promises, so you can do stuff like controller.set('contentA', model.posts); controller.set('contentB', model.comments); // or ... this.controllerFor('whatEver').set('content', model.whatever); } }); 

आशा करता हूँ की ये काम करेगा

अन्य सभी उत्कृष्ट उत्तरों के लिए धन्यवाद, मैंने एक मिक्सिन बनाया जो एक सरल और पुन: उपयोग करने योग्य इंटरफ़ेस में सबसे अच्छा समाधान जोड़ता है। यह आपके द्वारा निर्दिष्ट मॉडल के लिए afterModel के बाद एक Ember.RSVP.hashafterModel Ember.RSVP.hash को निष्पादित करता है, फिर setupController में नियंत्रक में गुणों को setupController । यह मानक model हुक में हस्तक्षेप नहीं करता है, इसलिए आप अभी भी सामान्य रूप में परिभाषित करेंगे।

उदाहरण उपयोग:

 App.PostRoute = Ember.Route.extend(App.AdditionalRouteModelsMixin, { // define your model hook normally model: function(params) { return this.store.find('post', params.post_id); }, // now define your other models as a hash of property names to inject onto the controller additionalModels: function() { return { users: this.store.find('user'), comments: this.store.find('comment') } } }); 

यहाँ मिश्रण है:

 App.AdditionalRouteModelsMixin = Ember.Mixin.create({ // the main hook: override to return a hash of models to set on the controller additionalModels: function(model, transition, queryParams) {}, // returns a promise that will resolve once all additional models have resolved initializeAdditionalModels: function(model, transition, queryParams) { var models, promise; models = this.additionalModels(model, transition, queryParams); if (models) { promise = Ember.RSVP.hash(models); this.set('_additionalModelsPromise', promise); return promise; } }, // copies the resolved properties onto the controller setupControllerAdditionalModels: function(controller) { var modelsPromise; modelsPromise = this.get('_additionalModelsPromise'); if (modelsPromise) { modelsPromise.then(function(hash) { controller.setProperties(hash); }); } }, // hook to resolve the additional models -- blocks until resolved afterModel: function(model, transition, queryParams) { return this.initializeAdditionalModels(model, transition, queryParams); }, // hook to copy the models onto the controller setupController: function(controller, model) { this._super(controller, model); this.setupControllerAdditionalModels(controller); } }); 

https://stackoverflow.com/a/16466427/2637573 संबंधित मॉडल के लिए ठीक है हालांकि, एम्बर सीएलआई और एम्बर डेटा के हाल के संस्करण के साथ, असंबंधित मॉडल के लिए एक सरल दृष्टिकोण है:

 import Ember from 'ember'; import DS from 'ember-data'; export default Ember.Route.extend({ setupController: function(controller, model) { this._super(controller,model); var model2 = DS.PromiseArray.create({ promise: this.store.find('model2') }); model2.then(function() { controller.set('model2', model2) }); } }); 

यदि आप केवल मॉडल 2 के लिए वस्तु की संपत्ति को प्राप्त करना चाहते हैं, तो DS.PromiseArray के बजाय DS.PromiseObject का उपयोग करें:

 import Ember from 'ember'; import DS from 'ember-data'; export default Ember.Route.extend({ setupController: function(controller, model) { this._super(controller,model); var model2 = DS.PromiseObject.create({ promise: this.store.find('model2') }); model2.then(function() { controller.set('model2', model2.get('value')) }); } }); 

MilkyWayJoe के उत्तर में जोड़ना, धन्यवाद btw:

 this.store.find('post',1) 

रिटर्न

 { id: 1, title: 'string', body: 'string string string string...', author_id: 1, comment_ids: [1, 2, 3, 6], tag_ids: [3,4] }; 

लेखक होगा

 { id: 1, firstName: 'Joe', lastName: 'Way', email: 'MilkyWayJoe@example.com', points: 6181, post_ids: [1,2,3,...,n], comment_ids: [1,2,3,...,n], } 

टिप्पणियाँ

 { id:1, author_id:1, body:'some words and stuff...', post_id:1, } 

… मेरा मानना ​​है कि लिंक पीठ महत्वपूर्ण हैं ताकि पूरा संबंध स्थापित हो। उम्मीद है कि किसी को मदद करता है

आप beforeModel या afterModel हुक का प्रयोग कर सकते हैं क्योंकि ये हमेशा कहा जाता है, भले ही model नहीं बुलाया गया हो, क्योंकि आप गतिशील क्षेत्रों का उपयोग कर रहे हैं।

एसिंक्रोनस रूटिंग डॉक्स के अनुसार:

मॉडल हुक में विराम-पर-वायर्ड बदलाव के लिए कई उपयोग के मामलों को शामिल किया गया है, लेकिन कभी-कभी आपको संबंधित हुक की सहायता से पहले मॉडल और बाद में मॉडेल की आवश्यकता होगी। इसके लिए सबसे आम कारण यह है कि यदि आप किसी डायरेक्ट्री URL खंड से {{link-to}} या संक्रमण के माध्यम से एक मार्ग में संक्रमण कर रहे हैं (यूआरएल परिवर्तन की वजह से संक्रमण के विपरीत), मार्ग के लिए मॉडल पहले से ही निर्दिष्ट हो चुके हैं (उदाहरण के लिए {{# link-to 'आलेख' लेख}} या this.transitionTo ('आलेख', आलेख)), जिसके मामले में मॉडल हुक को नहीं कहा जाएगा। इन मामलों में, आपको किसी भी तर्क के लिए या तो मॉडेल या मोडेल हुक के इस्तेमाल का उपयोग करना होगा, जबकि राउटर अभी भी सभी प्रकार के मॉडलों को एक संक्रमण करने के लिए इकट्ठा कर रहा है।

तो कहें कि आपके SiteController पर एक themes प्रॉपर्टी है, तो आप ऐसा कुछ कर सकते हैं:

 themes: null, afterModel: function(site, transition) { return this.store.find('themes').then(function(result) { this.set('themes', result.content); }.bind(this)); }, setupController: function(controller, model) { controller.set('model', model); controller.set('themes', this.get('themes')); }