9 Replies Latest reply on Jun 19, 2009 2:36 PM by GordonSmith

    How to call a function

    Jerry62712 Level 1

      As part of my attempts to make FLEX 508 compliant, I've tried several things.  But this question is about basic FLEX in general.  What I'm trying to do is to call a routine (that will someday work and make FLEX compliant I hope).  Here is the basic layout in the mxml file:

       

        <mx:Script source="/scripts/FSUtil.as" />
        <mx:Script source="/scripts/FSCalc.as" />
        <mx:Script source="/scripts/FSLangSwitch.as" />

       

        <mx:Script>
            <![CDATA[
                accessibleSet();
            ]]>
        </mx:Script>

       

      "accessibleSet" is located in the FSUtil.as file.  The error from the invocation above is:

      1180: Call to a possibly undefined method accessibleSet.

       

      This is what it looks like (note the code creates an error):

      public function accessibleSet():void {
          headerDHSImage.accessibilityProperties.description = 'State of Illinois Department of Human Services logo';
      }

       

      The error is:

      1120: Access of undefined property headerDHSImage.

      But I don't think the basic idea of calling a function from the script section of an mxml file is affected by this.

       

      Just for completeness, headerDHSImage is defined in a component called DHSHeader.mxml as:

          <mx:Image id="headerDHSImage"
              source="images/DHSLogo.gif"
              toolTip="State of Illinois Department of Human Services Logo"
              left="5" top="5"/>

      This component is displayed when the application runs so I know that connection is working.

       

      Recap:

      I want to call a function from the script area of an mxml file, but am not sure of the protocol.

       

      Thanks,

      Jerry

        • 1. Re: How to call a function
          Michael Borbor Level 4

          You must wrap that call within a function , only imports, var 

          declarations and metatags are allowed outside of a function.

          • 2. Re: How to call a function
            BennyBeta Level 4

            Michael's right... so try something like this:

             

            <mx:Application

            creationComplete="init()">


            <mx:Script>

            <![CDATA[

            public function init():void

            {

            accessibleSet();

            }

            ]]>

            </mx:Script>


            </mx:Application>

             

            Let me know if that helps...

             

            Ben Edwards

            1 person found this helpful
            • 3. Re: How to call a function
              Jerry62712 Level 1

              Yes, that took care of the error in the initial invocation of the accessibility routine.  But I'm not clear why.  If I understand it at all, then in the mxml application tag you can only refer to functions that are within a naked script tag (only locally).  That is, you can't refer to a function that is in an associated script file via the script source method.

               

              I appreciate both of your help with this matter.  At least while I'm trying to understand it, it is working.

               

              I'm wondering if the next problem is of the same type.  That function is trying to set the accessibility of an object that is in a component that is included in the mxml.  Specifically, component DHSHeader.mxml has an image on it.  "headerDHSIMage" is the id of it.  My routine which is in FSUtil.as which is in turn included on the main mxml by a script/cource will try to set the accessibility for the image (similar to using an "alt" property in HTML).

               

                  headerDHSImage.accessibilityProperties.description = 'State of Illinois Department of Human Services logo';

               

              This produces an error (1120: Access of undefined property headerDHSImage.) - is it caused by a scope issue like the calling of the function was?

              • 4. Re: How to call a function
                Michael Borbor Level 4

                you seem to be making your first steps in AS3, when you define variables,

                functions, classes you also define the scope than can be public, private,

                protected, internal, all these scopes define whether something can be access

                or not, and from where it can be accessed.

                1 person found this helpful
                • 5. Re: How to call a function
                  GordonSmith Level 4

                  > If I understand it at all, then in the mxml application tag you can only refer to functions

                  > that are within a naked script tag (only locally).  That is, you can't refer to a function

                  > that is in an associated script file via the script source method.

                   

                  No, this is incorrect. There is no difference between declaring a function like accessibleSet() within the <Script> tag and declaring it in an AS file included by a <Script> tag. The problem is where you can call that function from. You normally do not write "loose code" in a <Script> tag like

                   

                  <Script>

                      accessibleSet();

                  </Script>

                   

                  If you do, it actually becomes part of an autogenerated class initialization ("cinit") method emitted by the compiler, which isn't what you're expecting, because at class initialization time no instances even exist and you can only read and write static vars.

                   

                  Another way to understand it is this: When you write an MXML file, you are writing a class. For example, suppose you write MyApp.mxml as

                   

                  <mx:Application>

                      <mx:Script>

                          accessibleSet();

                      <mx:Script>

                      <mx:Button id="b"/>

                  </mx:Application>

                   

                  This is more-or-less equivalent to writing the AS class

                   

                  public class MyApp extends Application

                  {

                      accessibleSet();

                   

                      var b:Button = new Button();

                  }

                   

                  If you are familiar with writing classes, you should see the problem here: A class body doesn't normally contain loose function calls or other loose statements. Instead, a class body is supposed to contain 'const', 'var', and 'function' declarations. So you need to call a method like accessibleSet() inside another method -- such as an event handler -- that runs at a well-defined time.

                   

                  BTW, you are probably going to confuse yourself further if you continue splitting your code for a single application into multiple AS files which you then include with <Script> tags. All of this code goes into one class and therefore it really belongs either inside the <Script> tag itself or in a single AS file brought in by a single <Script> tag. You need to think in terms of classes, not files.

                   

                  Gordon Smith

                  Adobe Flex SDK Team

                  • 6. Re: How to call a function
                    Jerry62712 Level 1

                    Thank you for the info!

                     

                    I do have a question on it, however.  I'm familiar with java, but certainly not an advance or expert level coder.  You used the term "loose" and I'm not familiar with it in the context of classes.  Could you expand on that a little.

                     

                    I understand the "time line" problem of calling a function "before its time".  I need to call this before it is presented to the user so I can add all the accessibility features I can, but after the objects that are going to be modified are created of course.  Could you expand on that a little?

                     

                    Finally, each of my .AS files are for a unique function so when it comes to maintenance you will be able to know exactly what to work on for what function.  I'm converting a java application to FLEX.  It is one I've worked on, but didn't write.  I found it hard to navigate to the class (usually involved several for each function) that needed to be changed.  So I have a script that will call the class that does the processing for example.  That class will create a class that has the standard values (usually a set of arrays but some individual values).  My hope is to have those populated from a DB2 database when I can figure out how to do that.  But that is for another thread and just to give you some background.

                     

                    Anyway, I really appreciate your informative reply!

                    • 7. Re: How to call a function
                      GordonSmith Level 4

                      The normal stuff you put in a class are declarations of its consts, vars, and functions (along with import statements):

                       

                      public class MyClass

                      {

                          import somewhere.OtherClass;

                       

                          private static const ONE:int = 1;

                       

                          private var myObject:OtherClass;

                       

                          private function doSomething():void

                          {

                              myObject = new OtherClass();

                          }

                      }

                       

                      By "loose code" I mean other statements, such as trying to do

                       

                      public class ClassWithLooseCode

                      {

                          for (var i:int = 0; i < 10; i++)

                          {

                              trace(i);

                          }

                      }

                       

                      You normally don't put loose code in a class because it runs too early to be useful -- before any components exist!

                       

                      A good place to put code that needs to run early -- after a component exists but before the user can interact wtih it --  is in handlers for the 'preinitialize', 'initialize', or 'creationComplete' events. The  'preinitialize' event is dispatched after the component is created but before its children have been created. The 'initialize' event is dispatched after it has been added as a child of its parent, and its children have been created (i.e., it has its whole family). The 'creationComplete' event is dispatched after the LayoutManager has given it a size and location.

                       

                      I don't advise putting every method in its own file... when you have many classes, each with many methods, that will be very confusing. Most developers put all the code for a single class in a single file, like we do in the source code for the Flex framework (which you can look at).

                       

                      Gordon Smith

                      Adobe Flex SDK Team

                      1 person found this helpful
                      • 8. Re: How to call a function
                        Jerry62712 Level 1

                        Again, thanks for helping a newbie with this.

                         

                        Ben gave an example of the creationComplete event on the application tag.  I just wanted to understand it better to get a wider view of the whole thing.

                        • 9. Re: How to call a function
                          GordonSmith Level 4

                          You could just do

                           

                              <mx:Application initialize="accessibleSet()"/>

                           

                          But some people like to do it like this

                           

                              <mx:Application initialize="initializeHandler(event)"/>

                           

                          and then declare the method

                           

                              private function initializeHandler(event:Event):void

                              {

                                  accessibleSet();

                              }

                           

                          in the <mx:Script>. I favor the latter method because you might want to do a variety of things in response to an initialize event and I think MXML like

                           

                              <mx:Application initialize="doThis(); doThat(); doSomethingElse()"/>

                           

                          is awkward, especially if you want to get into if/else/then statements, for-loops, etc.

                           

                          Gordon Smith

                          Adobe Flex SDK Team