2012-12-18 19 views
9

मैं विरासत में एम्बर एप्लिकेशन को दोबारा करने पर काम कर रहा हूं, जिसमें काफी गैर-एमवीसी विकार है। मैं चीजों को यथासंभव मॉड्यूलर रखने की सोच रहा हूं, और कोड डुप्लिकेशन को रोकने में मदद के लिए कई स्क्रीनों में विभिन्न यूई घटकों का पुन: उपयोग करने की उम्मीद कर रहा हूं।Ember.js - मैं नेस्टेड/बार-बार विचारों में आउटलेट को कैसे लक्षित करूं, और ऐसे यूई लेआउट के लिए सर्वोत्तम प्रथाएं क्या हैं?

ऐसा लगता है कि आउटलेट ऐसा करने का सबसे अच्छा तरीका है।

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

{{#each item in controller}} 
     {{view App.ItemThumbView}} 
{{/each}} 

इस दृश्य का दायां साइडबार एक आउटलेट है जो चयन के आधार पर बदलता है। जब मैं कोई आइटम चुनता हूं, तो मैं templatized उप-दृश्य के भीतर संपादन संचालन की एक सूची प्रदर्शित करना चाहता हूं, जो चयनित होने पर, नेस्टेड आउटलेट के माध्यम से उचित संपादन UI प्रकट करता है।

मूलतः

+---------------------------------------------------+ 
|  Parent Pane 
| 
| +------------------------------+ +----------+ 
| | Device Section    | | Sidebar | 
| |        | | [Outlet] | 
| | +--------+ +---------+  | |   | 
| | | Dev 1 | | Dev 2 |  | |   | 
| | |[outlet]| | [outlet]|  | +----------+ 
| | +--------+ +---------+  | 
| +------------------------------+ 
+--------------------------------------------------+ 

नेस्टेड बार देखा गया सभी का हिस्सा एक ही नियंत्रक - जो समझ में आता है - लेकिन मैं उसके संगत आउटलेट से किसी चयनित दृश्य कनेक्ट करने में सक्षम होने की जरूरत है। कनेक्टिंग आउटलेट पर मेरे शुरुआती प्रयास कभी प्रदर्शित नहीं होते हैं। कोड बिल्कुल असफल नहीं होता है, इसलिए नियंत्रक बस एक छुपा आउटलेट अपडेट कर रहा है।

एम्बर में घोंसला वाले दृश्य के लिए मैं सही आउटलेट कैसे लक्षित करूं? (सबसे अच्छा, मैं साइडबार आउटलेट हिट करने में सक्षम हूं, लेकिन एक नेस्टेड डिवाइस टेम्पलेट के भीतर आउटलेट नहीं।) और क्या यह पहली जगह एम्बर में प्रासंगिक मेनू को लागू करने के लिए एक उचित संरचना है?

* स्पष्टीकरण के लिए मेरे वर्तमान सेटअप के साथ, प्रत्येक डिवाइस आइटम को उसी टेम्पलेट का उपयोग करके प्रस्तुत किया जाता है। चयनित होने पर, साइडबार आउटलेट कुछ डिवाइस की मेटा जानकारी के साथ अपडेट होगा, जबकि चयनित डिवाइस दृश्य अपने आउटलेट को एक संपादन मेनू से भी कनेक्ट करेगा। केवल एक डिवाइस आइटम में एक समय में 'एडिट' आउटलेट जुड़ा होगा।

क्या यहां एक आउटलेट का उपयोग करने का अर्थ है, या क्या मुझे संपादन मेनू को आवश्यकतानुसार प्रदर्शित करने के लिए टेम्पलेट में सशर्त तर्क छोड़ना चाहिए? को फिर से करने के लिए

अद्यतन सवाल की सर्वोत्तम प्रथाओं भाग:

दुकानों decoupling घटकों, और भविष्य-प्रूफिंग संभावित दृश्य nestings के लिए महान होने लगते हैं। लेकिन अभी ऐसा लगता है कि घोंसला वाले दृश्य के लिए सही आउटलेट तक पहुंचना थोड़ा बोझिल है। इसके अलावा, यदि आप हमेशा जानते हैं कि टेम्पलेट के भीतर कौन सा घटक सशर्त रूप से घोंसला जाएगा, तो यह आपके विचारों को केवल हार्डकोड करने के लिए आसान लगता है। उदाहरण:

// within template used for individual result-list items 
{{#if condition }} 
    {{view reusableSubView}} 
{{/if} 

यहां चीजों को करने का पसंदीदा एम्बर तरीका क्या है? क्या आउटलेट बनाने के लिए कोई ओवरहेड है जो हर समय कनेक्ट नहीं हो सकता है?

उत्तर

13

ठीक है, इसके साथ घूमने के घंटों और घंटों के बाद, ऐसा लगता है कि सशर्त रूप से मेरे घोंसले के दृश्य से ऊपर एक स्तर पर नामित आउटलेट शामिल है।

ऐसा इसलिए है क्योंकि आपको टेम्पलेट के भीतर लक्षित करने के लिए एक एकल, विश्वसनीय आउटलेट की आवश्यकता है, और प्रोग्रामटाइम को रनटाइम पर आउटलेट नाम देने का एक अच्छा तरीका प्रतीत नहीं होता है।

आगे, जिस आउटलेट को आप लक्षित करने की उम्मीद करते हैं, वह रूटर्स, नियंत्रकों और स्क्रीन की वर्तमान स्थिति को प्रस्तुत करने के लिए प्रयुक्त टेम्पलेट्स के घोंसले में एक मूल टेम्पलेट के भीतर कहीं मौजूद होने की आवश्यकता है। यदि किसी पैरेंट रूट ऑब्जेक्ट द्वारा आउटलेट नहीं रखा गया है, तो आप इसे अपने लीफ-नोड रूट में लक्षित करने की उम्मीद नहीं कर सकते हैं।

मुझे एक उदाहरण के साथ स्पष्ट करने दें:

के बाद से मैं मूल रूप से मेरे प्रश्न पूछा, हमारे यूआई लोगों की एक सूची के लिए उपकरणों की एक सूची से बदल गया है, लेकिन सिद्धांत ही रहता है।

मेरे पास उनकी तस्वीरों वाले लोगों की एक सूची है, और उन्हें उनके परिणाम के बगल में कुछ और जानकारी दिखाने के लिए क्लिक किया जा सकता है।

<script type="text/x-handlebars" data-template-name="people" > 
    <h3>People in this group</h3> 
    <div class="peeps"> 
     {{#each controller}} 
      {{ view App.PersonView }} 
      {{#if selected }} 
        <div class='too-personal'> 
        {{ outlet veryPersonalDetails }} 
        </div> 
      {{/if}} 
     {{/each}} 
    </div> 
</script> 

और इस तरह थोड़े है कि एक व्यक्ति टेम्पलेट:

मुझे लगता है कि तरह दिखता है एक लोगों टेम्पलेट

<script type="text/x-handlebars" data-template-name="person" > 
     {{#linkTo person this}} 
      <div data-desc="person-item" class="item"> 
       <div class="portrait"> 
        <img class="avatar" {{bindAttr src="gravatarUrl"}}/> 
       </div> 
       <div class="statuslabel"><span {{bindAttr class=":label statusLabel"}}>{{statusText}}</span></div> 
       <div class="cTitle">{{fullName}}</div> 
      </div> 
     {{/linkTo}}  </script> 

और विवरण अतिरिक्त जानकारी और संपादन विकल्प के साथ खाका

<script type="text/x-handlebars" data-template-name="person/details" > 
various edit options  
</script> 

किसी व्यक्ति के परिणाम पर क्लिक करने पर, मेरा राउटर यूआरएल उठाता है अपडेट करें, और विवरण टेम्पलेट में अभिभावक लोगों के टेम्पलेट में स्टब्स करें।

App.Router.map(function() { 
... 
    this.resource('people', { path: '/people'}, function() { 
     this.resource('person', { path: '/:person_id' }, 
      function() { 
       this.route('details'); 
      } 
     ); 
    }); 

}); 
व्यक्ति मार्गों के साथ

:: मेरी रूटर कुछ इस तरह की स्थापना की है

App.PeopleRoute = Ember.Route.extend({ 
    model: function() { 
     return App.People.find(); 
    }, 
    setupController: function(controller, model) { 
     controller.set('content', model); 
    } 
}); 

App.PersonRoute = Ember.Route.extend({ 
    model: function(params) { 
     return App.People.peepsById[params.person_id]; 
    }, 

    setupController: function(controller, model) { 
     this._super(controller, model); 
     var person = model; 
// this block ensures that only one person has a selected status at a time 
// ignore the overly-verbose code. I'm cleaning it up tomorrow 
     var ls = App.People.lastSelected; 
     if (ls) { 
      ls.set('selected', false); 
     } 
     person.set('selected', true); 
     App.People.lastSelected = person; 
     controller.set('content', model); 
    }, 

    renderTemplate: function() { 
     // person is actually stored in router 'context' rather than 'model' 
     // omg! 
     var x = this.controllerFor('personDetails').set('content', this.get('context')); 
     this.render('person/details', { // render person/details 
      into:'people', // into the people template 
      outlet: "veryPersonalDetails", // at the veryPersonalDetails outlet 
      controller: x // using the personDetails controller for rendering 
     }); 

// additional rendering in sidebar outlet for testing 
     this.render('person/details',{ 
      into:'people', 
      outlet: "personDetails", 
      controller: x 
     }); 

     console.log("@@@ we did it!"); 
    } 
}); 

मैं मूल रूप से PersonView भीतर आउटलेट करने की कोशिश की है, लेकिन यह मेरा व्यक्ति टेम्पलेट के रूप में कार्य नहीं करेगा, वास्तव में लोगों के मार्ग के भीतर प्रस्तुत किया गया था। जब तक व्यक्ति व्यक्ति मार्ग तक पहुंच जाता है, तब तक नियंत्रक सूची में सभी लोगों को पहले से ही प्रस्तुत कर चुका है। जिस व्यक्ति को मैं लक्षित करना चाहता हूं वह बहुत पहले से पारित हो चुका है।

मार्ग और माता-पिता और वांछित बाल टेम्पलेट्स के बीच मध्यस्थ के रूप में मार्ग कार्य करके, मैं ऐसा करने में सक्षम था।

अंत में, टेम्पलेट्स के भीतर नेस्टेड दृश्यों को स्पष्ट रूप से घोषित करने के लिए या केवल आउटलेट का उपयोग करने के सवाल के संबंध में, मेरा मानना ​​है कि आउटलेट बहुत साफ हैं। हालांकि इस समाधान में मार्गों के चारों ओर काम करने में थोड़ा सा शामिल था, लेकिन अत्यधिक जटिल टेम्पलेट ऑब्जेक्ट्स रखने के लिए यह काफी बेहतर है। अब मैं आशा करता हूं कि कुछ भी छूए बिना टेम्पलेट्स के मनमाने ढंग से जटिल घोंसले को प्राप्त कर सकते हैं लेकिन उनके प्रतिपादन में शामिल मार्ग शामिल हैं।

आगे, यह समाधान अप्रयुक्त आउटलेट के ओवरहेड को समाप्त करता है। मेरा मानना ​​है कि आपको खाली कंटेनर ऑब्जेक्ट्स के समूह के साथ 'डोम' को कूड़ेदान के बजाय केवल आउटलेट का उपयोग करना चाहिए।

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^