Question

I have a MXML with a form, and inside it, two TextInputs. I hate having any piece of code inside the MXML file (I come from a JavaScript formation) so I use a

mx:Script source="external.as"

tag to include any code used in any MXML file. The problem is that if I have this code on the external.as file:

private function populateFromForm():void{
   var vo:ValidObject= new ValidObject();
   vo.market = marketInput.text;
   vo.segment = segmentInput.text;
   vo.priceLow = priceLowInput.text;
   vo.priceHigh = priceHighInput.text;
}

Where marketInput, segmentInput, priceLowInput and priceHighInput are TextInputs defined in the MXML file. When I try to complile I get a 1120: Access to undefined property XXXXX

I have tried adding this lines prior to the function:

public var marketInput:TextInput;
public var segmentInput:TextInput;
public var priceLowInput:TextInput;
public var priceHighInput:TextInput;

But instead I get a 1151:A conflict exists with definition XXXX in namespace internal which makes perfect sense.

Is there a way to do this without having to pass all the input references to the function as parameters of it?

Was it helpful?

Solution

Doing a "code-behind" is painful in Flex. There is no concept of partial classes or the flexibility of prototypal inheritance as in Javascript. Google for "code-behind in flex" for many resources.

I think it's better you get used to the idea of embedding code in mxml. Use script tags avoiding inline code as much as possible. If you have to write a lot of code within MXML, perhaps you may want to re-factor the code into multiple custom components. Bonus points if they are reusable.

OTHER TIPS

You need to create a reference to an instance of the TextInputs' parent container, and then use that reference to accsess the TextInputs and their properties. I think we need some clarification on your file structure. How are you creating the instance of the parent container? I'm thinking this is what you need to do:

MyForm.mxml:

<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:TextInput id="marketInput" />
    <mx:TextInput id="segmentInput" />
    <mx:TextInput id="priceLowInput" />
    <mx:TextInput id="priceHighInput" />
</mx:VBox>

SaveVOContainer.as:

package
{
    public class SaveVoContainer extends Container
    {
        private var myForm:MyForm = new MyForm();

        public function SaveVOContainer
        {
            this.addChild(myForm);
        }

        private function populateFromForm():void{
           var vo:ValidObject= new ValidObject();
           vo.market = myForm.marketInput.text;
           vo.segment = myForm.segmentInput.text;
           vo.priceLow = myForm.priceLowInput.text;
           vo.priceHigh = myForm.priceHighInput.text;
        }
    }
}

The canonical way to do code-behind in Flex is via inheritance. Here's a good explanation from the docs: http://learn.adobe.com/wiki/display/Flex/Code+Behind. In a nutshell:

  1. Declare an ActionScript class to use as your base class.
  2. Set the base class as the root container in your MXML file.
  3. For any controls declared in your MXML file, you have to redeclare them as public members of the base class using the exact same name (exactly as you are doing above for your script block with source tag, only it works :-)

So, your ActionScript file:

package mypackage
{
    import mx.controls.TextInput;

    public class myClass extends WindowedApplication
    {
        public var marketInput:TextInput;

        private function populateFromForm():void{
            /* As above */
        }
    }
}

And the corresponding MXML file:

<?xml version="1.0" encoding="utf-8"?>
<custom:myClass xmlns:custom="mypackage.*"
        xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark" 
        xmlns:mx="library://ns.adobe.com/flex/mx">
    <mx:TextInput id="marketInput"/>
</custom:myClass>

Et cetera for your other TextInput controls. And now your populateFromForm function should work.

It is kind of heinous to have to redeclare the same entities twice, but it's not quite the bag of hurt the earlier respondent made it out to be (although it's possible this changed in Flex 4 to make it less painful than it was).

  • import this in .AS:

    import mx.core.Application;

  • in the .AS use this:

    mx.core.Application.application.component.property = value; mx.core.Application.application.myText.text = 'test';

do you have a script tag in your mxml file that points to your ActionScript file?


<mx:Script source='includes/foo.as' />

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top