RSS
 

Archive for the ‘Flex’ Category

AdvancedDataGrid: Adventures in binding

18 Sep

Quick post on AdvancedDataGrid dataProviders.

If your using a HierarchicalData provider for you AdvancedDataGrid (Flex) binding changes may (will) not be picked up by the AdvancedDataGrid.

For example


<mx:AdvancedDataGrid id="grid" bottom="10" top="40" left="10"
designViewDataType="tree" width="379">
<mx:dataProvider>
<mx:HierarchicalData source="{grades}"
childrenField="assignments"/>
</mx:dataProvider>
<mx:columns>
<mx:AdvancedDataGridColumn headerText="Course" dataField="title"/>
<mx:AdvancedDataGridColumn headerText="Score" dataField="scoreString" width="80"/>
</mx:columns>
</mx:AdvancedDataGrid>

Won’t pickup the update to ‘grades’. Instead you’ll need to update the dataProvider itself…


var hd:HierarchicalData = new HierarchicalData();
hd.childrenField = "assignments";
hd.source = grades;
grid.dataProvider = hd;

 
4 Comments

Posted in Flex

 

Flex Modules Watch Your Scope

14 Aug

Here’s another help hint for those working with Modules in Flex: Watch your variable scope!!

When loading modules, you have a number of options for loading the SWF including the ModuleLoader and ModuleManager. If neither of those fit your needs you always have access to Flash’s Loader class. ModuleManger can be used for fine grained control of the loading process. Either way, variable scope plays a crucial roll in the loading process.

Here’s an example using ModuleLoader…

public function loadSWFModule(swfURL:String):void
{
var moduleLoader:ModuleLoader = new ModuleLoader();
moduleLoader.url = swfURL;

moduleLoader.addEventListener(ModuleEvent.READY,onModuleLoaded);
moduleLoader.addEventListener(ModuleEvent.ERROR,onModuleError);
moduleLoader.addEventListener(ModuleEvent.PROGRESS,onProgress);
moduleLoader.loadModule();
}

The moduleLoader is declared as a local variable. As it turns out this will cause problems, even with the ‘strong’ event listeners. For those not wanting to read the technical details to follow, simply use avoid using a locally scoped variable.

The following are some of the symptoms you may run into using the latter locally scoped variable:

To help those searching the net, I’ll be a bit redundant in the ‘symptom’ descriptions so hopefully you’ll find this post if you’ve stumbled upon this problem

Symptons

  • The module fails to load the first time, but loads successfully the second time.
  • The ModuleEvent.READY is never dispatched
  • The ModuleInfoProxy never picks up the ModuleEvent.READY dispatched by ModuleInfo
  • ModuleInfo.clearLoader() throws an error (which is quietly caught), Error #2029: This URLStream object does not have a stream opened when calling loader.close()
  • The problem comes in when the Loader finishes loading the SWF. ModuleInfo’s internal listener list (listeners attached during ModuleInfoProxy’s constructor) are lost (i.e. null) when ModuleInfo finally reaches it’s readyHandler( ) method. At the end of the readyHandler( ), a ModuleEvent.READY event is dispatched.

    dispatchEvent(new ModuleEvent(ModuleEvent.READY));

    With the listener list being null, the event is never picked up by the ModuleInfoProxy and the initial load fails.

    On subsequent loads (i.e. the second time) ModuleInfoProxy’s load( ) method checks to see if the info has already been loaded and dispatches the ModuleEvent.READY event directly.

    else if (info.loaded)
    {
    //trace("Module[", url, "] load is already loaded");
    if (info.setup)
    {
    ...
    if (info.ready)
    {
    ...
    dispatchEvent(new ModuleEvent(ModuleEvent.READY));
    }
    }
    }

    Causing the load to ‘work’ the second time.

    My understanding is that Garbage Collection is often invoked when a module is loaded. It looks like it’s the cause of this behavior (the listeners being lost). I assumed that the ‘strong’ listeners would be enough to keep the GC away, oh well.

    Again the solution is simple, make sure your not using a locally scoped variable when loading modules.

     
    13 Comments

    Posted in Flex, Modules

     

    Dashboards…Flex’s Sweet Spot

    06 Aug

    Thanks Adobe!!!

    I’ve taken on a number of Flex projects over the past 2-3 years. In that time I’ve used Flex to meet many types of business needs. I’ve spent the last few months working on a enterprise dashboard application built with Flex. This past week the time came for the executives’ ‘sneek peek’ of the project’s progress. The feedback, in their words,

    “Beyond all expectation.”

    I can’t remember having more fun architecting and implementing a project. Dashboards seem to be Flex’s ‘sweet spot’, IMHO. Adobe [Flex] provides so rich a toolset for this type of project, one can’t help but have fun working on dashboards with Flex. Talking with other local Flex developers only resonates the view that Flex + Dashboards are a perfect fit. So once again, thanks to Adobe for this great product, it’s been an absolute joy to work with.

    FYI, the project is using Flex, AMFPHP 1.9, ActiveMQ JMS + BlazeDS, Multicore PureMVC, PureMVC’s Pipes, MySQL to name a few (i.e. a mouthful of open source technologies). BTW, it scales beautifully with dynamic modules using PureMVC Pipes. Thanks too, to Cliff Hall for PureMVC!!

    For those pessimists our there, I can post again once I’ve developed the printouts (Printing is notoriously painful in Flex :) ).

     
    No Comments

    Posted in Flex

     

    AMFPHP Class Mapping Primer [1.9 beta]

    01 Jul

    Thought I’d post a simple AMFPHP class mapping primer.

    I ran into a wall after re-arranging my VO / DAO package structure on the server, learned a few things in the process and thought I’d post .

    I’m assuming your using AMFPHP 1.9 beta.

    Class mapping allows your php backend and actionscript frontend to pass strongly typed variables back and forth. The benefits are obvious so I won’t cover them here.

    If your not after any detailed information here’s a quick set of samples classes to get you going.

    PHP

    
    // LoginVO.php is saved as {$voPath}/com/dl/app/LoginVO.php
    class LoginVO
    {
       var $_explicitType="com.dl.app.LoginVO";
       public $username;
       public $password;
    }
    

    AS

    package com.dl.common.Login.model.vo
    {
       [RemoteClass(alias="com.dl.app.LoginVO")]
       public class LoginVO
       {
          public var username:String;
          public var password:String;
       }
    }

    That’s it. If your after more options and detailed info, keep reading.

    Sending Strongly Typed Objects from PHP to ActionScript via AMFPHP

    In PHP

    You have a few options (choose one).

  • Your class can declare a variable named $_explicitType;
  • The most common approach is to use the $_explicitType class member:

    class LoginVO
    {
       var $_explicitType="com.dl.app.LoginVO";
       public $username;
       public $password;
    }
    
  • You can set $GLOBALS['amfphp']['outgoingClassMappings']['localclass'] = ‘remoteclassAlias‘;
  • e.g.

    $GLOBALS['amfphp']['outgoingClassMappings']['myclass'] = "com.dl.myapp.MyClass";

    Note that the local class name associative key (‘myclass’ above) must be in lowercase with the current release of AMFPHP.

  • Rely on the reflection class (PHP 5+)
  • If your install of PHP has the ReflectionAPI you can let AMFPHP do the work *for* you. I found a few cavets using this approach on servers who’s OS uses backslashes natively. If this is the case, AMFPHP will only send the name of the class and not include any package info. There are two simple code changes you can make in AMFPHP to get around this, just drop me a line if your interested (hopefully they’ll be commited in the next release of AMFPHP).

    In actionscript

    Here to, you have a some options,

  • Use [RemoteClass] metadata tag to specify the remote class alias
  • package com.dl.common.Login.model.vo
    {
       [RemoteClass(alias="com.dl.app.LoginVO")]
       public class LoginVO
       {
          public var username:String;
          public var password:String;
       }
    }
  • Use registerClassAlias()
  • registerClassAlias(“com.dl.app.LoginVO”,LoginVO);

    Make sure your actionscript project contains a reference to the class. See my previous post for more info.


    Sending Strongly Typed Objects from ActionScript to PHP via AMFPHP

    In PHP

    Rely on the class having been registed in ActionScript with the server’s correct package [directory] structure (relative to AMFPHP’s VO base path $GLOBALS['amfphp']['customMappingsPath']). If this is the case you, your all set.

    Note: If you haven’t already you’ll need to make sure $voPath is pointing to the correct directory in AMFPHPs global.php

    Define $GLOBALS['amfphp']['incomingClassMappings']['remoteclassAlias'] = ‘localclassPackage‘. (e.g. $GLOBALS['amfphp']['incomingClassMappings']['com.dl.as3.userVO'] = ‘com.dl.userVO’);

    In ActionScript

    Again, you’ll need to use one of the two following…

  • Use [RemoteClass] metadata tag to specify the remote class alias
  • Use registerClassAlias()

    For more info check out

    AMFBaseSerializer.php’s getClassName() function

    AMFBaseDeserializer.php’s mapClass() function




     

    AMFPHP Complex Classes – Yeah I knew that

    19 Jun

    Just blew half an hour tracking down something I *knew* I’d done before. Thought I’d post here for future ‘lapses.’

    To return a typed object from PHP to the flashplayer the process is simple, declare a variable called $_expicitType in your PHP class
    e.g.
    class SummaryVO
    {
    var $_explicitType = "com.dl.SummaryVO";
    $standards = array();
    $levels = array()
    }

    In your corresponding ActionScript class use the RemoteClass metadata tag

    package com.dl
    {
    [RemoteClass(alias="com.dl.SummaryVO")]
    public class SummaryVO
    {
    public var standards:Array;
    public var levels:Array;
    }
    }

    Note the values for $_explicitType and alias are arbitrary, they can be what ever you’d like, as long as their the same in AS and PHP (provided your only conerned with PHP=>AS mapping).

    Okay, so what happens when you have ‘complex classes’ you’d like to return? Complex meaning a class who’s members are made up of other ‘custom’ class instances.

    Let’s say, for example, that in our later code example ‘standards’ was an array of ‘StandardVO.’ The problem I ran into was that I was getting a typed ‘SummaryVO’ back from AMFPHP, however my class members were not typed, just generic objects. I checked and I had taken the necessary steps to use strongly typed SummaryVO and StandardVO classes, yet the StandardVO was coming back as a plain old Object.

    We’ll it turned out in my development flurry I hadn’t used a reference to the ‘StandardVO’ class yet!! Simply declaring an instance of StandardVO did the trick (i.e. var placeHolder:StandardVO). You could also you the includes class [...] compiler option.

    Moral of the story, be sure the complier includes a reference to any class you want strongly typed from your RPCs.

     

    Pipe Demo: Mortgage App

    17 Jun

    I’ve posted a pipes version of the mortgage app.

    Things to note:

    You can load / unload the modules dynamically.

    A junction mediator is defined for each ‘player.’ In the mortgage app context that’s a mediator for the application itself, the Acme widget and the Foo widget.

    ApplicationJunctionMediator
    ModuleJunctionMediator (Acme)
    ModuleJunctionMediator (Foo)

    To make our lives easier when it comes time to unload the module, the module caches the app’s pipe fitting it’s connected to. This allows the module to easily ‘cleanup’ (disconnect our fittings) should we want to unload the module. You may find a cleaner approach to this, feel free to post in comments – the ‘caching approach’ was simple and thus the road taken for the demo.

     
     

    Pipe Architecture

    13 Jun

    Here’s a working architecture for modular applications utilizing PureMVC pipes.

    Pipe Architecture

    This allows you to have modules that load modules that load modules, etc. The modules communicate to each other via Pipes.

    The sample diagram illustrates a parent, child, grandchild relationship (An app that loads a module that loads module). You can of course, have multiple siblings.

     

    Dynamic Modules … General Tips

    21 May

    Okay, for those of you getting ready to work with dynamic modules, I thought I’d share a few minor points I picked up on this past week.
    Your application must include a reference to any interfaces the module implements.

    <mx:Moudule implements"com.company.project.SomeInterface">

    You’d want a reference to com.company.project.SomeInterface in your main app.
    Likewise if the module has subclassed Module

    public class MyModule extends Module

    You’ll need a reference to MyModule in your main app as well.

    There are compiler options to include these references, however I find it easiest to just declare a variable of the corresponding type.

    i.e. var interfaceDef:ICustomInterface

    If you find yourself wanting to create your own ‘View’ class in PureMVC it’s pretty straightforward. Just ensure that you subclass the controller as well.

    Here’s a sample facade utilizing a custom view class…

    protected override function initializeController( ):void
    {
    if ( controller != null )
    return;
    controller = CustomController.getInstance( multitonKey );
    }

    // Our custom View subclass in action
    protected override function initializeView( ):void
    {
    if ( view != null )
    return;
    view = CustomView.getInstance( multitonKey );
    }

    And the custom controller…

    public static function getInstance( key:String ) : IController
    {
    if ( instanceMap[ key ] == null )
    instanceMap[ key ] = new CustomController( key );
    return instanceMap[ key ];
    }

    override protected function initializeController( ) : void
    {
    view = CustomView.getInstance(multitonKey);
    }

    Finally, our custom View

    public static function getInstance( key:String ) : IView
    {
    if ( instanceMap[ key ] == null )
    instanceMap[ key ] = new CustomView( key );
    return instanceMap[ key ];
    }

    In practice the view in initialized in the controller’s initializeController() method, so without subclassing your Controller you still maintain the standard View.

     
     

    Dynamic Flex Modules with PureMVC

    19 May

    I’m rolling out a large project, and I wanted to utilize dynamic modules for scalability.

    For those who aren’t familiar will modules, basically, there a great way to encapsulate “pieces” of your application. A trivial example would be a small ‘shell application’ that once the user logs in, loaded the appropriate use-case module. If your working in a team environment modules make for an easy project divide-and-conquer approach.

    I’ve been using the PureMVC framework lately and figured adding support for dynamic modules wouldn’t be too difficult as Cliff and the gang have already been hard at working getting the framework changes in place to make this possible (replacing singletons with multitons etc).

    Well after some working laying this out, I’m glad to say I’ve got it working. Check out this sample app Dynamic Mortgage Demo.

    The demo allows the user to get loan quotes from [fictional] banks. The demo allows the user to dynamically load / unload bank “modules.”

    The application and modules are very well encapsulated. Here’s whats required from each party…

    Application:

    Must compile with…

    A reference to any interfaces the modules loaded at runtime implement (ILoadableModule in our case).

    A reference to any subclasses of mx:Module the modules are using (PureMVCLoadableModule in our case). This is only necessary if your subclassing mx:Module.

    That’s it.

    Here’s the integration point on the modules end…

    The modules facade implements an “InitializeMapping” function which maps application notification names to local (module) notification names [inbound mapping]. The function also defines module notification name to application notification name [outbound] mappings.

    Here’s an example

    override public function initializeMappings():void
    {
    outboundMappings:Array = new Array();
    outboundMappings[QUOTE_GENERATED] = EventNames.LOAN_QUOTE_READY;

    inboundMappings = new Array();
    inboundMappings[EventNames.REQUEST_FOR_LOAN] = QUOTE_REQUESTED;
    }

    And thats the extent of what our application and modules know of each other. The rest of the ‘work’ is done automatically by a few interfaces / subclasses I wrote on top of PureMVC to make this possible. (i.e. your modules facade subclasses ModuleFacadeBase etc). No framework changes we’re required just some subclassing here and there.

     

    Flex Canvas – Rounded Corners & cornerRadius

    04 Mar

    After struggling to get my custom components (based on canvas) to render with rounded corners, I found this link.

    Problem
    Even after utilizing the cornerRadius property, my containers were not rendering with rounded corners.

    Solution
    You simply need to ensure that borderStyle property is set to solid. If a border is not desired, set the borderThickness to zero.

     
    9 Comments

    Posted in Flex

     

    Client.Data.UnderFlow

    13 Feb

    I ran across the following error today, Client.Data.UnderFlow undefined? I’m using AMFPHP to enable my RPC calls. As it turns out, I the variable I was returning was of a different type than I had declared in my methodTable.

     
    No Comments

    Posted in AMFPHP, Flex

     

    Flex Architecture Frameworks

    03 Jan

    I’m gearing up to start some medium scale enterprise projects and thought I’d look up this “Cairngorm” thing I heard talked about at the MAX conference in Chicago. The developers either loved or hated it, so I figured I should check it out. Basically Cairngorm is a design pattern framework for flex, an architect’s tool chest if you will. We’ll it appears that Cairngorm isn’t alone, here’s the lineup I ran across today…

    Cairngorm

    PureMVC

    APR

    Tom Bray’s EasyMVC

    Simeon Bateman’s EasyMVC

    (EasyMVC’s share the same name but are, in fact, different frameworks)

    The latter two (EasyMVC’s) appear to be lighter weight frameworks, while Cairngorm and PureMVC both seem to be a bit more robust. PureMVC isn’t just for flex it currently supports or is in the process of been implemented in … Flex, Flash, AIR, FlashLite, .NET, Windows Mobile, Silverlight, J2ME, SE, EE, JavaFX, and well… PHP and ColdFusion.

    I’m reading into all four frameworks to decide which, if any to further evaluate. I may adopt one for my upcoming projects or use them as spring boards to writing my own framework to help enforce the DP’s I’ve been studying as of late.