8 Replies Latest reply on Oct 27, 2007 3:36 AM by uwe.jugel

    passing mxml-component references to sub functions

    uwe.jugel
      Hello,

      i want to do something like this:

      watch pseudo code in pastebin



      // Pseudo Flex ;)
      <app creaCompl="init()">
      <DataGrid id="grid"/>
      <script>
      func init(){
      easyConnect( "loginCheckerWebservice", grid )
      }

      func easyConnect(aString, aGrid){
      ws = new HTTPService() // this works...
      ws.setDetails... //using info from aString

      // now comes the tricky part
      ws.addEventListerner(ResultEvent.RESULT,function(){
      Alert.show(ws.lastResult.message.my.path.join(", ")) // this works with the ...my.path Array
      aGrid. dataProvider = ws.lastResult.my.path // this does not work
      }
      }
      </script>
      </app>



      The "easyConnect" function would reside in a package and thus cannot access the "grid" directly so it has to use the aGrid reference. I also want to pass the whole grid for the sake of spmlicity of the "easyConnect" function it should simply connect "aThingByString" to aRealObject (and later become more intelligent: like "aSting" to "a2ndString" or anObject to anOtherObject and so on)

      I can't simply change the dataProvider !? OK, but WHY ?

      Or maybe a better Question: How do i change the dataProvider (and maybe the columns, clolumnText and so on)

      Thy for any help,
      Juve
        • 1. Re: passing mxml-component references to sub functions
          Gregory Lafrance Level 6
          Are you getting an error? I'm wondering what type of undesiable result you are seeing.
          • 2. Re: passing mxml-component references to sub functions
            ntsiii Level 3
            i do not like anonymous functions, but try:
            function(event:ResultEvent){
            Alert.show(ws.lastResult.message.my.path.join(", ")) // this works with the ...my.path Array
            aGrid. dataProvider = event.result.my.path //

            Also, I advise setting resultFormat="e4x" and then i the handler>
            var xmlResult:XML = XML(event.result);
            trace(xmlResult.toXMLString())

            But really, dump that anonymous function. They are very hard to debug.

            Tracy
            • 3. Re: passing mxml-component references to sub functions
              uwe.jugel Level 1
              I tracked down the problem:

              the datagrid resides within a viewstack ("page" 2) and is not initialized when i want to call my binding function. But i want to use a viewstack because it has good usability within the UI designer.

              Is there a way to get access at app-start to uninitialized widgets residing within a viewstack ?
              I don't want to treat all bind handling within my viewchange logic, i want to separate bindings and view-flow.

              btw: thanks for the tip with dumping the anonymous function makes thing more readable for me

              Juve
              • 4. Re: passing mxml-component references to sub functions
                ntsiii Level 3
                "...access at app-start to uninitialized widgets residing within a viewstack ..."
                Yes, but it is a very bad thing to do, and I won't tell you yet.

                The correct way to handle this is to use binding or an event system that fetches the data when the ViewStach children are instantiated. Use the creationComplete event to fetch the data from the main app scope.

                Tracy
                • 5. Re: passing mxml-component references to sub functions
                  uwe.jugel Level 1
                  OK, i thought it was bad to use a Viewstack that way, but:

                  The viewstack has very good UI-Designer Usability --> i definately want to use it.
                  I want to handle all binding and all eventing within my package (you may call it API or better: my DSL).
                  There should be no hand written code within the declarative part --> i.e. i will NOT use mxml-code like:
                  <.. dataProvider="{}" /> or <.. text="{}"/> or <.. creationComplete="" /> or <.. change=""/>

                  Even though i like this way of binding your data, there are too many possibilites to bind stuff, you have to know:
                  a Labels Text is bindable by <mx:Label text="{}" />
                  but a Buttons Text binds with: <mx:Button label="{}" />
                  These decisions should be made by my package and not be the programmer using my package. He simply passes a Widget.

                  I want strong separation of UI-Design and UI-Logic. The Main app should only have two "small" parts and try to avoid any unnecessary code.
                  <app>
                  <script> include myPackage;

                  // this call needs access to the uiWidget0002 ... it must not be null
                  veryEasyDefineBindingWith( uiWidget0002 ).AndWebservice( " http://my-known-url/ws.xml" )

                  // this call needs access to the uiWidget0002 and its parents ... it must not be null
                  veryEasyDefineViewTransitionFrom( uiWidget001 ).To( uiWidget0002 ).When( userIsValid )
                  </script>
                  <viewstack id="uiViewstack">
                  <VBox>
                  <mx:Label id="uiWidget0001"/>
                  </VBox>
                  <VBox>
                  <mx:DataGrid id="uiWidget0002"/>
                  </VBox>
                  </viewstack>

                  As my functions receive a NULL Object at runtime currently, i can't attach an Eventhandler (not even an FlexEvent.CREATION_COPLTETE event).

                  You might notice that i did not name my Views (no ID). I know that i might not be a good practice but then again the user/programmer is tended to use two very similar IDs for the View (VBox: "materialList") and the containing Widget (DataGrid: "materialList" ?).
                  A View is a kind of abstraction that must be learned. Then you would name them: "materialListView" and "materialListTable". Naming Views might not be needed, the parent can be treated as implicit information, because there will always be a named Widget within a View (at least my API docu/guide will suggest that). (This might change, if testing/using my API fails).

                  I hope this helps to make my intend more understandable.

                  Juve
                  • 6. Re: passing mxml-component references to sub functions
                    uwe.jugel Level 1
                    bump !
                    I did try to work it out the last few days, but had no success.
                    Any Idea yet ?

                    Thx,
                    Juve
                    • 7. Re: passing mxml-component references to sub functions
                      ntsiii Level 3
                      The problem you are seeing is the effect of 'deferred instantiation". Deferred instantiation is the default for most of the navigation containers including ViewStack and Tabnavigator. The purpose of this is to increase the speed with which the application is first displayed. UI rendering is the most expensive part of a Flex app, so the less that has to happen before the use can interact with the app, the better the users experience.

                      The child views of the ViewStack do not even exist until a user navigates to them. That is why trying to access properties of components in ViewStack children is returning a null.

                      The way to defeat deferred instantiation is to set creationPolicy="all" on the container(ViewStack). Be aware of the cost of doing this. Try it to make sure that is your problem.

                      But I am sure you can find a way to do what you want without defeating this important function. Have a child component, on say ,creationComplete, call out to some known function on the main app, requesting the data. That way, you get the benefits of deferred instantiation.

                      Tracy
                      • 8. Re: passing mxml-component references to sub functions
                        uwe.jugel Level 1
                        Thanks, i'll try that.

                        I've come up with another way to do it yesterday.
                        The User (lay programmer) write something like this:

                        <app>
                        <script>
                        Build.DataBinding("someName")
                        .thatBindsWebservice(" http://i.know.this.url.from.external/myList.xml")
                        .To.aGrid.WithinView(view2)
                        .namely(myGrid)
                        </script>
                        <viewstack>
                        <container id="view1"><stuff.../></container>
                        <container id="view2"><DataGrid id="myGrid"/></container>
                        </viewstack>
                        </app>

                        My users will now have to specify the view, when talking about a views components.
                        Within my Builders WithinView function i call: container.createComponentFromDescriptors(true)
                        And as WithinView(view2) is called before namely(myGrid) the passed Grid is not Null anymore

                        It works similar to your suggestion but creationPolicy="all" looks like a better solution.

                        Thx, i'll try that and close this Thread on Monday, if everything works.

                        Juve