2012-06-18 19 views
13

में एक मार्ग से बाहर निकलने पर * नष्ट करने के लिए कैसे करें * नई एम्बर.जेएस रूटिंग सिस्टम (here वर्णित) के बारे में, यदि मैं सही ढंग से समझता हूं, तो मार्ग से बाहर निकलने पर विचार नष्ट हो जाते हैं।Ember.js

क्या मार्ग से बाहर निकलने पर विचारों को नष्ट करने का कोई तरीका है, ताकि जब दृश्य मार्ग में प्रवेश करता है तो दृश्य की स्थिति संरक्षित होती है?


अद्यतन: ऐसा लगता है कि जब तक आउटलेट दृश्य को नए मार्ग में नहीं बदला जाता है तब तक विचार नष्ट नहीं होते हैं। उदाहरण के लिए, यदि आप कुछ {{आउटलेट मास्टर}} में व्यूए के साथ राज्य ए में हैं और आप {{आउटलेट मास्टर}} में व्यूबी के साथ स्टेटबी पर जाते हैं, तो व्यूबी व्यूए को प्रतिस्थापित करेगा। इसके आस-पास एक तरीका है जब आपको विचारों को संरक्षित करने की आवश्यकता होती है, उदाहरण के लिए, {{आउटलेट मास्टर 1}}, {{आउटलेट मास्टर 2}}, {0 आउटलेट मास्टर 2}}, ...

एक अच्छी सुविधा एक सरणी पास करने की क्षमता होगी आउटलेट के विचारों के बारे में। और यह भी चुनने में सक्षम हो कि क्या मार्ग नष्ट हो जाएंगे या सिर्फ मार्ग से बाहर निकलने पर छुपाया जाएगा।

+5

जैक, मुझे लगता है कि आप उन अतिरिक्त सुविधाओं को पूरा कर सकते अगर आप अपने शीर्ष स्तर के आउटलेट एक 'ContainerView' बनाने: Ember.View.isEqualUnderscore isEqual का एक संशोधित संस्करण है। फिर आप 'बच्चों के दृश्य' संपत्ति के माध्यम से सीधे अपने बच्चों को कुशल बना सकते हैं, और यदि कोई बच्चा दृश्य हटा दिया गया है या सिर्फ छुपा हुआ है तो इसका नियंत्रण हो सकता है। –

उत्तर

9

मुझे पता है कि रूटिंग सिस्टम को कैसे संशोधित किया जाए, ताकि आउटलेट में डाले गए विचार नष्ट न हों। सबसे पहले मैं, हैंडल outlet सहायक ओवरराइड इतना है कि यह लोड करता है एक Ember.OutletView{{outlet}} में:

Ember.Handlebars.registerHelper('outlet', function(property, options) { 
    if (property && property.data && property.data.isRenderData) { 
    options = property; 
    property = 'view'; 
    } 

    options.hash.currentViewBinding = "controller." + property; 

    return Ember.Handlebars.helpers.view.call(this, Ember.OutletView, options); 
}); 

कहाँ Ember.OutletView फैली Ember.ContainerView इस प्रकार है:

Ember.OutletView = Ember.ContainerView.extend({ 
    childViews: [], 

    _currentViewWillChange: Ember.beforeObserver(function() { 
     var childViews = this.get('childViews'); 

      // Instead of removing currentView, just hide all childViews 
      childViews.setEach('isVisible', false); 

    }, 'currentView'), 

    _currentViewDidChange: Ember.observer(function() { 
     var childViews = this.get('childViews'), 
      currentView = this.get('currentView'); 

     if (currentView) { 
      // Check if currentView is already within childViews array 
      // TODO: test 
      var alreadyPresent = childViews.find(function(child) { 
       if (Ember.View.isEqual(currentView, child, [])) {   
        return true; 
       } 
      }); 

      if (!!alreadyPresent) { 
       alreadyPresent.set('isVisible', true); 
      } else { 
       childViews.pushObject(currentView); 
      } 
     } 
    }, 'currentView') 

}); 

असल में हम _currentViewWillChange() ओवरराइड और बस को हटाने के बजाय सभी childViews छिपाने currentView। फिर _currentViewDidChange() में हम जांचते हैं कि currentView पहले से ही childViews के अंदर है और तदनुसार कार्य करें।

Ember.View.reopenClass({ 
    isEqual: function(a, b, stack) { 
     // Identical objects are equal. `0 === -0`, but they aren't identical. 
     // See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal. 
     if (a === b) return a !== 0 || 1/a == 1/b; 
     // A strict comparison is necessary because `null == undefined`. 
     if (a == null || b == null) return a === b; 
     // Unwrap any wrapped objects. 
     if (a._chain) a = a._wrapped; 
     if (b._chain) b = b._wrapped; 
     // Compare `[[Class]]` names. 
     var className = toString.call(a); 
     if (className != toString.call(b)) return false; 

     if (typeof a != 'object' || typeof b != 'object') return false; 
     // Assume equality for cyclic structures. The algorithm for detecting cyclic 
     // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. 
     var length = stack.length; 
     while (length--) { 
      // Linear search. Performance is inversely proportional to the number of 
      // unique nested structures. 
      if (stack[length] == a) return true; 
     } 
     // Add the first object to the stack of traversed objects. 
     stack.push(a); 
     var size = 0, result = true; 
     // Recursively compare objects and arrays. 
     if (className == '[object Array]') { 
      // Compare array lengths to determine if a deep comparison is necessary. 
      size = a.length; 
      result = size == b.length; 
      if (result) { 
       // Deep compare the contents, ignoring non-numeric properties. 
       while (size--) { 
        // Ensure commutative equality for sparse arrays. 
        if (!(result = size in a == size in b && this.isEqual(a[size], b[size], stack))) break; 
       } 
      } 
     } else { 
      // Objects with different constructors are not equivalent. 
      if (a.get('constructor').toString() != b.get('constructor').toString()) { 
       return false; 
      } 

      // Deep compare objects. 
      for (var key in a) { 
       if (a.hasOwnProperty(key)) { 
        // Count the expected number of properties. 
        size++; 
        // Deep compare each member. 
        if (!(result = b.hasOwnProperty(key))) break; 
       } 
      } 
     } 
     // Remove the first object from the stack of traversed objects. 
     stack.pop(); 
     return result; 
    } 
}); 
+1

एक कंटेनर व्यू इस कस्टम लॉजिक को डालने के बजाय और अधिक पर्याप्त है (जो कि कंटेनर व्यू का कच्चा डुप्लिकेशंस है)। यह स्वीकार्य समाधान नहीं होना चाहिए। – Valer

+1

यह एक कंटेनर दृश्य है, और यह तर्क दुर्भाग्यवश (अभी भी) दृश्य टियरडाउन को रोकने के लिए आवश्यक है। – runspired

4

ताकि जब दृश्य मार्ग में प्रवेश करता है तो दृश्य की स्थिति संरक्षित होती है।

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

मैं एक उपयोग केस की कल्पना कर सकता हूं जहां यह बहुत उपयोगी नहीं होगा (उदाहरण के लिए एक लंबी सूची में एक विशिष्ट स्थिति पर स्क्रॉल करना) ताकि हो सकता है कि यह आपके प्रश्न का उत्तर न दे।

+0

हां, मैं एक साधारण चयन के बारे में बात नहीं कर रहा हूं, लेकिन ऐसे मामलों में जहां आपके पास एक लंबा फॉर्म हो सकता है जिसे उपयोगकर्ता ने आंशिक रूप से पूरा किया है, एक लंबी सूची को स्क्रॉल करने की स्थिति (जैसे आपने कहा) ... तो यह समझ में नहीं आता है उस जानकारी को नियंत्रक में संग्रहीत करें और फिर से दर्ज करने पर दृश्य अपडेट करें। एक और तरीका है व्यू इंस्टेंस को कंट्रोलर में स्टोर करना और हर बार जब आप मार्ग में प्रवेश करते हैं तो इसका इस्तेमाल करें। लेकिन मुझे उम्मीद थी कि एक बेहतर तरीका था। –

+0

अभी तक एक बेहतर तरीका हो सकता है: जो कोई एम्बर जानता है उससे बेहतर है (वहां बहुत सारे हैं) जवाब दे सकते हैं। :) – pjmorse