5 Replies Latest reply on Apr 2, 2012 3:52 PM by GurtnamonaIE

    Flex accessing bound variables prematurely

    GurtnamonaIE

      Trying to instantiate variables only when first accessed but Flex accesses everything, even before the referencing component is created. In below example, I wouldn't expect titleForScreen2 to be called immediately, yet it is. Is this a bug?

       

      <?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. Re: Flex accessing bound variables prematurely
          pauland Level 4

          http://help.adobe.com/en_US/flex/using/WS2db454920e96a9e51e63e3d11c0bf69084-7cb8.html

           

          It says:

           

          Single-view containers

          Single-view containers by default create all their children when the application first starts. You can use the

          creationPolicy property to change this behavior.

          • 2. Re: Flex accessing bound variables prematurely
            GurtnamonaIE Level 1

            Thanks for the response however the issue is not regarding component creation. If you set creationComplete handlers throughout, you'll see that the label on the second screen is never created (as it shouldn't). The entire issue is that Flex is accessing the variable titleForScreen2 even though <s:Label text="{titleForScreen2}"/> is never created and that variable is not used anywhere else. This seems to me to be erroneous behavior.


            • 3. Re: Flex accessing bound variables prematurely
              Flex harUI Adobe Employee

              It is not a bug.  The binding code is pretty eager about evaluating expressions.

              • 4. Re: Flex accessing bound variables prematurely
                GurtnamonaIE Level 1

                It does seem odd to me that binding is evaluated before the component is created but I guess that's just how Flex works. To acheive the desired behavior, I moved the binding code to actionscript inside a creationComplete handler. Hopefully this will not have adverse effects.

                • 5. Re: Flex accessing bound variables prematurely
                  GurtnamonaIE Level 1

                  BTW, for anyone interested here is the sample code modified for my current approach. For what it's worth, I fail to see the value in Flex registering bindings prior to the creation of the binding component but I'll be the first to admit I'm not the most knowledgable about this stuff; there could be a perfectly valid reason. Critiques more than welcomed.

                   

                  <?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>