Archive

Archive for February, 2008

AS3 data binding and component states

February 28th, 2008 No comments

If you ever developed a complex data-driven application, you probably stumbled upon the data binding nightmare. Altough a great feature in Flex (a central one in my opinion), it lacks a bit of control.

I needed a form with multiple states depending on the flavor of the edited object. This way, I could have common fields to all object types and add a couple of fields based on the object type. However, these fields’ values were bound to properties of the edited object. When selecting an object from the list, the fields should update themselves. Bindings are executed to set field values. Now, since I use form states, all fields are technically on the stage and all bindings will execute, regardless of the type of the selected object.

Basic example

I have a form to edit animal properties (number of legs, head size, etc.)

I have some extra fields depending on the animal type (mammals have fur length and density, birds have wing span, etc.)

Every animal type has an associated state:

<mx:Form>
    <mx:FormItem label="Legs">
        <mx:TextInput text="{animal.legs}"/>
    </mx:FormItem>
    <mx:states>
        <mx:State name="mammal">
            <mx:AddChild position="lastChild">
                <mx:FormItem label="Fur length">
                    <mx:TextInput text="{Mammal(animal).furLength}"/>
                </mx:FormItem>
            </mx:AddChild>
        </mx:State>
    </mx:states>
</mx:Form>

The animal variable is set when an element is selected from a list. It can be an instance of a custom class Mammal or Bird which extends the Animal class. The state also changes according to the type selected. The problem occurs when I select a non-Mammal. The binding will execute, expecting a Mammal for the TextInput’s text property. An error will be thrown saying that Bird (or other) could not convert to Mammal. This is to be expected, as the TextInput in question remains on the stage even if the state is invisible.

What’s the solution? Perhaps not the most neat, but it works: create extra variables for every type. Now you will have animal:Animal, mammal:Mammal and bird:Bird variables with their respective types. When an animal is selected, every type except the needed one is set to null. The animal variable still points to the selected animal. The MXML changes:

<mx:TextInput text="{mammal.furLength}"/>

What happens? When the bindings execute, if a Mammal is selected, the mammal variable is equal to a Mammal instance and everything is smooth. If a Bird is selected, the mammal variable is null and everything is smooth again. Hurray! It took me about 2 hours to figure out. If you have a better solution, please share.

Tags: ,

Why Adobe? Matrix version

February 21st, 2008 No comments

Tags:

Happy Valentine’s Day from the elePHPants

February 14th, 2008 No comments

Tags:

AIR Prerelease Tour

February 8th, 2008 No comments

I attended a presentation on Flex and AIR yesterday. Mike Potter was unable to come and was replaced by LordAlex Leon. The presentation began with a long description of Adobe applications and their integration, but an hour later finally reached AIR. The part about AIR was quite short and did not teach me anything new.

For those of you who don’t know, AIR is coming out soon. It stands for Adobe Integrated Runtime (or RIA backwards). It allows you to run Flash/Flex apps on the desktop, read and write local files, query SQLite databases… all this cross-platform.

I did learn something interesting from one of the slides though. BlazeDS has just been released under an LGPL licence. This technology allows real-time data pushing. For me, it means developing multiplayer games!

Tags: ,

Sending headers

February 7th, 2008 No comments

There are many reasons to send headers in the middle of you PHP script. Sometimes you want to redirect the user based on some computed information or display different content types (mime-type). Have you ever had a problem with PHP complaining about “output already sent”?

To solve this problem, there is a workaround with ob_start/ob_flush. As pointed out in a past comment, you can put ob_start in the beginning of the script and ob_flush at the end, thus preventing any output before the script finishes executing.

A more neat solution (in my opinion) is to review your output approach. You should not send any output before you are absolutely sure about it (why would you sent kilobytes of HTML if you’re going to redirect anyway?). My approach is to store output in a variable or a class and then send it when ready. I also try to limit html generation until after I processed my GET/POST requests.

Tags: , ,