2012-03-30 14 views
5

हाइबरनेट की आलसी लोड हो रहा है क्षमताओं मैं केवल जब आवश्यक सर्वर से मेरी फ्लेक्स यूआई अनुरोध डेटा के मॉडल हिस्सा बनाना चाहते थे से प्रेरित होकर। मैंने सोचा कि यह एक सार्वजनिक एक्सेसर जोड़ने जैसा आसान होगा जो परिवर्तनीय पहुंचने पर केवल सर्वर अनुरोध भेजता है।फ्लेक्स लेज़ी बंधन

public function get tab2AC():ArrayCollection 
{ 
    if(_tab2AC == null){ 
     //Request data from server 
    } 
    return _tab2AC; 
} 

समस्या है कि फ्लेक्स आवेदन लांच पर सभी बाध्य चर तक पहुँचने के लिए, भले ही संदर्भित घटक अभी बाकी है बनाया जा रहा है है। तो भले ही dataProvider="{tab2AC}" साथ डेटा ग्रिड अभी तक बनाया जाना है, सर्वर अनुरोध अभी भी बाहर चला जाता है, इस प्रकार "केवल जरूरत पड़ने पर" आलस्य को पराजित किया।

मैं एक creationComplete हैंडलर के अंदर सर्वर अनुरोध जगह के रूप में मैं अपने यूआई मॉडल दृश्य राज्य और मेरे विचार सर्वर अनुरोधों को अज्ञानी से अनभिज्ञ रखना चाहते हैं नहीं करना चाहती।

दिलचस्प बात यह है कि अगर मैं एक्सेसर के अंदर एक Alert.show("anything"); जोड़ने के लिए, यह के रूप में वांछित काम करता है।

अद्यतन: यहाँ एक पूर्ण उदाहरण है। ब्रेकपॉइंट्स सेट करें और आप देखेंगे कि फ्लेक्स दोनों चरों तक पहुंचता है, भले ही शीर्षक किसी भी बनाए गए घटक द्वारा फ़ॉरस्क्रीन 2 का उपयोग नहीं किया जाता है।

<?xml version="1.0" encoding="utf-8"?> 
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
xmlns:s="library://ns.adobe.com/flex/spark" 
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"> 
<fx:Script> 
    <![CDATA[ 
     private var _titleForScreen1:String; 
     private var _titleForScreen2:String; 

     public function get titleForScreen1():String { 
      if(_titleForScreen1 == null){ 
       //Server Request 
      }     
      return _titleForScreen1; 
     } 

     public function get titleForScreen2():String { 
      if(_titleForScreen2 == null){ 
       //Server Request 
      } 
      return _titleForScreen2; 
     } 
    ]]> 
</fx:Script> 

<mx:ViewStack> 
    <s:NavigatorContent label="Screen 1"> 
     <s:Label text="{titleForScreen1}"/> 
    </s:NavigatorContent> 
    <s:NavigatorContent label="Screen 2"> 
     <s:Label text="{titleForScreen2}"/> 
    </s:NavigatorContent> 
</mx:ViewStack> 
</s:Application> 
+1

मैं इसके लिए कुछ संदर्भ इस्तेमाल कर सकते हैं "समस्या यह है कि फ्लेक्स आवेदन लांच पर सभी के लिए बाध्य चर तक पहुँचने के लिए, संदर्भित घटक अभी तक निर्मित होता है, भले ही लगता है।"। रेफरेंसिंग घटक क्या है और "बाउंड वेरिएबल" क्या है। उनमें से एक फ्लेक्स के लिए इसे किसी भी तरह से एक्सेस करने के लिए बनाया गया होगा। यदि आपने अपना अधिक आर्किटेक्चर/कोड दिखाया है तो शायद हम उसे समझा सकें। – JeffryHouser

+0

यदि आपके पास अपने डिस्प्ले पेड़ पर डेटाग्रिड है जिसमें डेटाप्रोवाइडर है, तो यह बाध्य चर का उपयोग करने का प्रयास करेगा। आप जो भी पूरा करने की कोशिश कर रहे हैं उसके लिए कृपया अधिक कोड दिखाएं। –

+0

क्या आप कोड पोस्ट कर सकते हैं जहां डेटाग्रिड है? साथ ही, क्या आप डेटा क्लास के अधिक कोड पोस्ट कर सकते हैं जहां उपरोक्त गेटर रहता है? क्या आप एक कस्टम बाध्यकारी घटना का उपयोग कर रहे हैं? आप कहते हैं "यहां एक पूर्ण उदाहरण है," लेकिन मैं उलझन में हूं कि वास्तव में यहां वास्तव में होना चाहिए। –

उत्तर

0

तो, हाँ, कि बस रास्ता है यह है। चूंकि फ्लेक्स तुरंत बाइंडिंग का मूल्यांकन करता है, इसलिए मुझे समयपूर्व मूल्यांकन को रोकने के लिए सृजन तक बाध्यता में देरी होनी चाहिए। फ्लेक्स के अजीब व्यवहार को पूर्ववत करने के लिए अतिरिक्त काम की तरह लगता है, लेकिन यह कभी-कभी यह कैसे होता है।

<?xml version="1.0" encoding="utf-8"?> 
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
xmlns:s="library://ns.adobe.com/flex/spark" 
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"> 
<fx:Script> 
    <![CDATA[ 
     import mx.binding.utils.BindingUtils; 
     import mx.binding.utils.ChangeWatcher; 

     private var _titleForScreen1:String; 
     private var _titleForScreen2:String; 

     public function get titleForScreen1():String { 
      if(_titleForScreen1 == null){ 
       //Server Request 
      } 
      return _titleForScreen1; 
     } 

     public function get titleForScreen2():String { 
      if(_titleForScreen2 == null){ 
       //Server Request 
      } 
      return _titleForScreen2; 
     } 

     public function updateLabel1(value:String):void {screen1Label.text = value;} 
     public function updateLabel2(value:String):void {screen2Label.text = value;} 

     public function bindLabel1():void { 
      var changeWatcher:ChangeWatcher = BindingUtils.bindSetter(updateLabel1,this, "titleForScreen1"); 
     } 

     public function bindLabel2():void { 
      var changeWatcher:ChangeWatcher = BindingUtils.bindSetter(updateLabel2,this, "titleForScreen2"); 
     } 
    ]]> 
</fx:Script> 

<mx:ViewStack> 
    <s:NavigatorContent label="Screen 1"> 
     <s:Label id="screen1Label" creationComplete="bindLabel1()"/> 
    </s:NavigatorContent> 
    <s:NavigatorContent label="Screen 2"> 
     <s:Label id="screen2Label" creationComplete="bindLabel2()"/> 
    </s:NavigatorContent> 
    </s:NavigatorContent> 
</mx:ViewStack> 
</s:Application> 
0

अपने बयान, सच नहीं है tab2AC गेटर, लांच पर फ्लेक्स अनुप्रयोग द्वारा पहुँचा नहीं है के रूप में एक प्रमाण यहाँ पूर्ण आवेदन कोड है:

<?xml version="1.0" encoding="utf-8"?> 
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"> 

    <fx:Script> 
     <![CDATA[ 
      import mx.collections.ArrayCollection; 

      private var _tab2AC:ArrayCollection; 

      public function set tab2AC(value:ArrayCollection):void 
      { 
       _tab2AC = value; 
      } 

      [Bindable] 
      public function get tab2AC():ArrayCollection 
      { 
       if(_tab2AC == null){ 
        trace("THIS WILL NOT BE CALLED"); 
       } 
       return _tab2AC; 
      } 

     ]]> 
    </fx:Script> 

</s:Application> 

आप देख सकते हैं, ट्रेस नहीं होगा ट्रिगर हो जाएं, इसलिए आपकी समस्या किसी ऐप से कहीं से उस गेटर से कॉल करने के लिए आ रही है, इसे ढूंढने के लिए, ब्रेक पॉइंट डालें और फिर आवश्यकता होने पर "स्टेप रिटर्न" दें।

कहा जा रहा है, तो आप गेटर में इस तरह से सीधे आलसी लोड हो रहा है को लागू नहीं करना चाहिए के रूप में सेवा कॉल अतुल्यकालिक है।

+0

-1 जबकि असीमित टिप्पणी सही और महत्वपूर्ण है, आप बाध्यकारी को पूरी तरह से अनदेखा कर रहे हैं कि ओपी के साथ समस्याएं हैं। उनका एप्लिकेशन लॉन्च पर फ़ील्ड तक पहुंचता है क्योंकि यह ** किसी डेटा के लिए बाध्य है प्रदाता संपत्ति ** –

+0

आपको किसी को डाउनवॉट करने से पहले पढ़ना सीखना चाहिए। मैं आपके लिए प्रासंगिक भाग को हाइलाइट करता हूं: _So डेटाप्रिड = "{tab2AC}" के साथ डेटाग्रिड ** अभी तक ** बनने के लिए ** है और जब आप पूरी तरह से सुनिश्चित हैं, तो फिर से पढ़ें :) –

+0

मतलब यह है कि यह * पर है द्वितीयक टैब *, इसलिए नाम 'टैब 2 एसी', यह नहीं कि यह एप्लिकेशन में मौजूद नहीं है। –

0

क्यों एक नया ArrayCollection वापस वापस नहीं जब चर रिक्त है, तो ArrayCollection जब सर्वर कॉल रिटर्न पर स्रोत सेट?

+0

यह इस तथ्य को हल नहीं करता है कि फ्लेक्स ने समय-समय पर एक्सेसर को कॉल किया है (निर्माण से पहले डेटाग्रिड का पूर्ण जो ArrayCollection का संदर्भ देता है)। इसके अलावा मैं अपनी टिप्पणी से खड़ा हूं कि सर्वर कॉल की असीमित प्रकृति मूक है। चूंकि ऑब्जेक्ट संदर्भ द्वारा पास किए जाते हैं, जब कॉल प्रतिक्रिया निजी एसी अपडेट करती है तो यह एसी को डेटाग्रिड को खिलाती है (क्योंकि वे वास्तव में एक ही चीज़ हैं)। – Gurtnamona

+0

दाएं। कम से कम आपको कुछ _to_ वापसी देता है, जो कुछ _will_ अपडेट करता है। –

0

मुझे लगता है कि इस डिबगर का सिर्फ wonky व्यवहार, न कि जो साधारण निष्पादन में क्या होगा की तुलना में है। यदि आप कोई तर्क डालते हैं जो आपको यह निर्धारित करने में सक्षम करेगा कि फ़ंक्शन को कॉल किया गया था जो डीबगर (जैसे किसी लेबल पर टेक्स्ट सेट करना) में बंधे नहीं है, तो गेटर को कॉल नहीं किया जाता है। हालांकि, अगर आप वहाँ में एक बयान का पता लगाने में कहें, गेटर करता है कहा जाता हो

conundrum यह है कि आप इस विचार पर निर्भर होना चाहते हैं कि यह केवल डीबगिंग में होने वाला है, और जब आप डीबग प्लेयर का उपयोग कर रहे हों तो असली व्यवहार प्राप्त करना कितना महत्वपूर्ण है?

फ्लेक्स में
+0

समयपूर्व संदर्भ डीबगिंग से स्वतंत्र होता है। मेरे वास्तविक कोड में मैं देख सकता हूं कि सर्वर अनुरोध तब भी होता है जब डिबगिंग नहीं होती है। – Gurtnamona

2

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

मुझे पता है कि यह एक सुंदर लंगड़ा जवाब है, लेकिन यह सच है। मैं कई सालों से एक फ्लेक्स डेवलपर रहा हूं और इसकी बाध्यकारी सुविधा के साथ जटिल संबंध रहा है।साथ ही, इस समय, केवल एक चीज जो बाध्यकारी कार्यान्वयन में बदल गई है वह दो-तरफा बाइंडिंग करने की क्षमता है।


वैसे, वाक्य रचना मैं एक वादा लौटने के लिए एक संपत्ति के बजाय एक नियमित रूप से विधि का उपयोग करें चाहते हैं। गुण अक्सर सिंक्रोनस और सस्ते (-श) संचालन के रूप में पढ़े जाते हैं, जबकि एक विधि (विशेष रूप से एक जो वादा करता है) में अधिक लचीला अर्थ होगा। लाइनों 12 और 19 पर

+0

सहमत हैं लेकिन मुझे यकीन नहीं है कि मैं उन्हें पूरी तरह त्यागना चाहता हूं। चूंकि फ्लेक्स बंदूक कूदता है, इसलिए मुझे इसे बंदूक देने के लिए इंतजार करना पड़ता है। – Gurtnamona

+0

अधिक जटिल मुखौटा होने से कम समय में कॉल करने में सक्षम होता है और समय सही होने पर उन्हें बंद कर देता है, मुझे डर है कि आप एसओएल हैं :( –

+0

मेरा समाधान सृजन पर बाइंडिंग करने के लिए पूर्ण है। बाइंडिंग सेट करना एएस एमएक्सएमएल जितना आसान नहीं है लेकिन ऐसा लगता है कि यह चाल चल रहा है। अगर आपके पास कोई पल है, तो कृपया मेरा जवाब देखें और मुझे बताएं कि आप क्या सोचते हैं। – Gurtnamona

1
<?xml version="1.0" encoding="utf-8"?> 
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
       xmlns:s="library://ns.adobe.com/flex/spark" 
       xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"> 
    <fx:Script> 
     <![CDATA[ 
      import mx.controls.Alert; 
      private var _titleForScreen1:String; 
      private var _titleForScreen2:String; 

      public function get titleForScreen1():String { 
       if(_titleForScreen1 == null){ 
        //Server Request 
       }     
       return _titleForScreen1; 
      } 

      public function get titleForScreen2():String { 
       Alert.show("test"); 
       if(_titleForScreen2 == null){ 
        //Server Request 
       } 
       return _titleForScreen2; 
      } 
     ]]> 
    </fx:Script> 

    <mx:ViewStack> 
     <s:NavigatorContent label="Screen 1"> 
      <s:Label text="{titleForScreen1}"/> 
     </s:NavigatorContent> 
     <s:NavigatorContent label="Screen 2"> 
      <s:Label text="{titleForScreen2}"/> 
     </s:NavigatorContent> 
    </mx:ViewStack> 
</s:WindowedApplication> 

ब्रेकप्वाइंट, प्रत्येक के दौरान स्टैक ट्रेस की जाँच, यह भी आप खुले बाध्यकारी पॉप कर सकते हैं और (वहाँ भी एक ब्रेकपाइंट ड्रॉप) wrapFunctionCall पर एक नज़र डालें। तो जब यह 12 और 1 9 पंक्तियों तक पहुंच जाता है, तो यह पूर्ण घटना को प्रेषित करने वाले प्रीलोडर की वजह से उन्हें 2 बार हिट करता है। मैंने प्रत्येक फ़ाइल में ब्रेकपॉइंट्स लगाए जो स्टैक-ट्रेस ने निष्पादन पथ को आगे बढ़ाया। दुर्भाग्यवश मुझे उस बिंदु को नहीं मिला जहां यह 2 कॉल होने का कारण बन गया था (उन हिस्सों में होना चाहिए जिनके पास मेरे पास स्रोत नहीं है) ऐसा लगता है कि ट्रेस में हर जगह केवल एक बार बुलाया गया था, लेकिन मुझे लगता है कि wrapFunctionCall को दो बार बुलाया गया था उन दो निष्पादन की अवधि। ऐसा होने वाला तीसरा ऐसा करने के लिए कॉल करने के कारण होता है, जो कि सिस्टम मैनेजर वाले सभी बच्चों के लिए बाइंडिंग पर निष्पादित करने के लिए कॉल करता है, इसलिए ऐसा लगता है कि घटकों के पास सिस्टम मैनेजर है, भले ही वे अभी तक जोड़े नहीं गए हों मंच या बनाया गया। क्षमा करें मेरे पास एक और ठोस जवाब नहीं है कि इनमें से प्रत्येक को क्यों होना है, लेकिन मेरा अनुमान है कि कुछ अच्छा कारण है।

आह हाँ लगभग भूल गया, यह भी आप अलर्ट दिखाया गया है यह एक त्रुटि का कारण बनता है देखेंगे लेकिन उस त्रुटि Binding.as में wrappedFuncitonCall विधि में कब्जा कर लिया है

catch(error:Error) 
    { 
     // Certain errors are normal when executing a srcFunc or destFunc, 
     // so we swallow them: 
     // Error #1006: Call attempted on an object that is not a function. 
     // Error #1009: null has no properties. 
     // Error #1010: undefined has no properties. 
     // Error #1055: - has no properties. 
     // Error #1069: Property - not found on - and there is no default value 
     // We allow any other errors to be thrown. 
     if ((error.errorID != 1006) && 
      (error.errorID != 1009) && 
      (error.errorID != 1010) && 
      (error.errorID != 1055) && 
      (error.errorID != 1069)) 
     { 
      throw error; 
     } 
     else 
     { 
      if (BindingManager.debugDestinationStrings[destString]) 
      { 
       trace("Binding: destString = " + destString + ", error = " + error); 
      } 
     } 
    }