Swiz 0.6.2 with Flex 4 support

We just released a new Swiz update:

  • Flex 4 support (beta)
  • TwoWay autowire
  • Mediate priorities
  • Pass event to mediating method

Flex 4 support
Today Adobe has released Flex Flash Builder 4 and Flash Catalyst betas on Adobe Labs. One more reason for Swiz to support Flex 4.
We have now posted two SWCs for Flex 2/3 and one for Flex 4. To compile the library on your own you now have to add a new compiler statement because we are using conditional compilation to support Flex 4:

-define=CONFIG::flex4,true

or for Flex 2/3:

-define=CONFIG::flex4,false

so the compiler args for Flex 4 read like:

-keep-as3-metadata+=Autowire,Mediate -namespace http://swiz.swizframework.org manifest.xml -include-namespaces http://swiz.swizframework.org -define=CONFIG::flex4,true

Further to let Swiz work in Flex 4 your beans in a BeanLoader have to be wrappend in a declarations tag:

<?xml version="1.0" encoding="utf-8"?>
<swiz:BeanLoader
	xmlns:fx="http://ns.adobe.com/mxml/2009"
	xmlns:mx="library://ns.adobe.com/flex/halo"
	xmlns:swiz="http://swiz.swizframework.org">
 
	<fx:Declarations>
		<ctrl:TestController id="testController" xmlns:ctrl="example.ctrl.*" />
	</fx:Declarations>
 
</swiz:BeanLoader>

If you use the SwizConfig tag in your main application MXML you also have to nest it into a declarations tag. Our first tests with Flex 4 are fine but since this is the first release with it please give use feedback that all works as expected. Also note that Flex 4 is still beta so there might be changes in the future.
Our internal change is that for Flex 4 we are now using FlexGlobals.topLevelApplication to get access to the Application and the SystemManager. We think that should be it and our Flex 4 test projects works fine. If you have any problems with Flex 4 please let us know and post a comment here and/or join the Swiz group on Google code.

TwoWay autowire
Ben has added twoWay autowire which is really cool and already demonstrated it in his awesome Swiz example project. In short you can now do:

[Bindable]
[Autowire( bean="appModel", property="activeView", twoWay="true" )]
public var activeView:int;

So when you change the activeView variable above also appModel.activeView will be changed.

Mediate priorities
The mediate annotation has a new attribute priority which should be self explaining:

[Mediate(event="FooEvent.FOO", priority="0")]
public function secondHandler():void
{
 
}
[Mediate(event="FooEvent.FOO", priority="1")]
public function firstHandler():void
{
	// I am called first because of higher priority
}

Pass event to mediating method
Now you have got the possibility to pass over the event to a mediating method instead of properties:

[Mediate(event="FooEvent.FOO")]
public function eventHandler(event:FooEvent):void
{
 
}

So the rule is when no properties are defined Swiz first tries to call the method without arguments. This is wrapped in a try/catch block so when this fails we call the method again with the event itself as argument. We try to avoid too much “magic” in Swiz but I think in this way it’s pretty handy.

Example
Event:

package
{
	import flash.events.Event;
 
	public class FooEvent extends Event
	{
 
		public static const FOO:String = "foo";
 
		public function FooEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=true)
		{
			super(type, bubbles, cancelable);
		}
 
		override public function clone():Event
		{
			return new FooEvent(type, bubbles, cancelable);
		}
 
	}
}

Because dispatchEvent returns false when the event is canceled your view code, in this example opened as popup, could look like this:

// note that the event bubble flag has to be set to true
if(dispatchEvent(new FooEvent(FooEvent.FOO))
{
	// event not canceled
	// usecase could be to close a popup when an event wasn't canceled like:
	PopupManager.removePopup(this);
}
else
{
	// event is canceled, this is what happens in this example with the controller code below
}

So let’s have a look at the controller which mediates the FooEvent:

[Mediate(event="FooEvent.FOO", priority="0")]
public function secondHandler():void
{
	// I will not be called in this example because event.stopImmediatePropagation() in firstHandler
}
[Mediate(event="FooEvent.FOO", priority="1")]
public function firstHandler(event:FooEvent):void
{
	event.stopImmediatePropagation();
	// note that the event cancelable property has to be true to cancel it
	event.preventDefault();
}

So what happens with the code above:
Because firstHandler has a higher priority than secondHandler it will be called first. In the method we call stopImmediatePropagation so the secondHandler will not be invoked. The event itself gets canceled with preventDefault and the view if statement is false and will not close the popup.

Have fun!

30 comments to Swiz 0.6.2 with Flex 4 support

  • mrm

    Great work guys! I had checked out the project from svn today and couldn’t for the life of me figure out what were the correct compiler settings to get rid of the CONFIG::flex4 error. In the end, I removed those bits of code and compiled using Flex 3.x SDK and now it works like a charm! I think you should also update pom.xml with that compiler statement.

  • Thanks mrm, if you would like to provide a patch for the pom.xml we are happy to integrated it.

  • mrm

    I’d love to, but I have no experience using Maven.

  • Hehe, no problem. We also have to check out if Flex Mojos supports conditional compilation flags.

  • mrm

    Ok, I think I found something. I’ll send the patch using the Google Code issue tracker.

  • Vitor

    My previous compiler settings was:

    -locale en_US -keep-as3-metadata+=Autowire

    and now I’ve putted:

    -locale en_US -keep-as3-metadata+=Autowire,Mediate -namespace http://swiz.swizframework.org manifest.xml -namespace http://swiz.swizframework.org -define=CONFIG::flex4,true

    and i removed the -include-namespaces just for -namespace

    Is this correct?

  • No, you should copy the line like I posted it. Check the docs here: http://livedocs.adobe.com/flex/3/html/help.html?content=compilers_25.html

  • Right now, the maven build is not functioning. Don’t worry, I will have it squared away, I’ve just got a lot of things going on that need to be tied up.

  • Thanks for the fantastic work. I’ve just moved from Cairngorm to Swiz and love it.

    Question: I was trying to get Swiz to work in FB 4 (with new swc) but am having trouble getting a model defined in the base .mxml class autowired. I’m using the MXML tag like so

    And the model attribute is defined in the same file in the fx:script section….

    [Bindable][Autowire(bean=”someModel”)]
    public var model:SomeModel

    and defined in the Beans.mxml…

    but when tracing out model onCreationComplete(), I’m getting an null (and my viewStack, which should be responding to changes in a model attribute, isn’t changing).

    Any thoughts?

    Thanks again,

    Daniel

  • creationComplete is a bit too early. Swiz hasn’t autowired your main view yet. If you have an AIR app you could use applicationComplete. Otherwise implement the IInitializingBean interface in one of your bean classes like a controller to have an entry point for your application.

  • Sönke,

    Thanks for the idea. Turns out applicationComplete is still too early. I tried implementing IInitializingBean on one of my controllers, but it’s not called automatically. Perhaps this isn’t implemented for the FB4 version?

    Thanks,

    Daniel

  • Sönke,

    Sorry, I’ll move this discussion to the forum.

    But just to follow up my last post…it looks like initialize() IS called, but is called before the application’s own preinitialize() event is launched.

    That’s why my logger wasn’t showing traces from the initialize() method…the logger itself hadn’t been setup yet.

    I’m more confused now because I’m not sure how to use the initialize() method as an entry point b/c it is called so early in the application’s lifecycle.

    Thanks,

    Daniel

  • Yes, the autowire of IInitializingBean happens during preInitialize when Swiz wires things together.
    Like you mentioned in your first comment this doesn’t work for views. A view gets autowired during addedToStage which I think happens between creationComplete and applicationComplete (AIR).

  • flashvnn

    Humm, i have problem with FlashBuilder 4 plugin for Eclipse, can someone give me a simple demo use Swiz with FlashBuilder 4, thank a lot.

  • In general there is no difference with Flash Builder 4. Just copy the swc in the libs directory of your project and you are ready to go.
    In Flex 4 the only difference is that the SwizConfig has to be inside a Declarations tag like also the beans in a BeanLoader.

  • flashvnn

    When set “-keep-as3-metadata +=Autowire,Mediate -namespace http://swiz.swizframework.org manifest.xml -include-namespaces http://swiz.swizframework.org -define=CONFIG::flex4,true”

    i get error “unknown configuration variable ‘include-namespaces'”, how i can fix it ?

  • Perhaps you missed something. When you set the compile args: -keep-as3-metadata +=Autowire,Mediate -namespace http://swiz.swizframework.org manifest.xml -include-namespaces http://swiz.swizframework.org -define=CONFIG::flex4,true
    it works fine here. are you using the standalone or plugin version of flash builder?

  • flashvnn

    Hi Sönke
    i’m using plugin version of flash builder

  • I am using standalone but I am pretty sure it should work. I would suggest you post your problem to the Swiz mailinglist because there are for sure already devs using Flex 4 this way.

  • flashvnn

    humn, i downloaded and install standalone but still get problem, can you make simple demo and share your project with configure?

    Thank

  • drop me a mail and I can send it to you (soenke.rohde gmail com).
    btw: you only need this to compile swiz itself and not for any projects you do with swiz. then you only have to download the swc and put it into the libs directory.

  • Jason Chen

    Hi, I am kind of confused about the “twoWay” attribute. I have been using Java/SpringFramework for the past 4,5 years and I know that if it’s a singleton bean, there is only one set of values in a single instance of bean. All the other objects are only holding a “reference” to that bean. If one bean holder changes the value in the bean, then the value will be changed for all the other bean with the same reference (i.e. ), so it’s always “twoWay” in Java/Spring. How is it different from the Swiz in Flex? Can someone explain a little bit more details? Should we make the “twoWay” the default behavior? When a bean is “Autowired”, the AS object should only hold a reference to that bean if it’s an object, isn’t it? Then when the data got modified, next time when the same AS object got injected to a view, should the value be there? I am hoping it’s not “copying” the value into a new object in the view. It should be just a “reference”, right? Or it doesn’t work that way in actionscript?

  • Hi Jason,
    the example is:
    [Bindable]
    [Autowire( bean=”appModel”, property=”activeView”, twoWay=”true” )]
    public var activeView:int;

    So activeView is an int meaning a primitive and no object. So when the view holding this property is added to the stage Swiz injects the value appModel.activeView into the activeView property. Now when you would change the value activeView without twoWay=”true” appModel.activeView would not be changed and when set to true it will be changed because a ChangeWatcher acts behind the scenes.

    However, this only applies to primitives.

  • Spoke with Chris and Ben earlier this week about making the necessary changes to support automatic bindings for non-primitives as well. For standard [Autowire] statements, it makes sense to only inject the requested instance at initialization. However, when binding to a particular property in an injected bean, it makes sense to always establish the binding as those properties may change over time. In my particular use case, I was implementing the PresentationModel pattern and using autowire-by-property to inject and observe properties in a PresentationModel from a Model bean. The automatic bindings provide a very elegant solution for synchronizing changes made to the Model back to the PresentationModel.

    Chris made the changes on his local snapshot of the code – hope to see this change rolled into the next release.

  • That should have read: “…when autowiring* to a particular property in an injected bean…”

  • Dwong

    Just wanted to add to this insightful blog that I’ve found a way to, in a sense, have the initialize() in IInitializingBean in the view.

    Since mxml bindings work with Autowiring beans, all you do is inject some bean into your view and listen to that via mxml tag. I haven’t found a way to add this binding in actionscript – it appears that adding it too early or too late causes the binding to not occur, and thus no “notification” on the view-side that Swiz has finished auto-wiring.

  • Erik Reedstrom

    I switched over to the latest nightly build, currently 4.0.0.12589, and noticed that the [Autowire] tags in the views are no longer auto-wiring.

    There is no dispatch of an event for addedToStage, so handleAutowireEvent is never being fired. This works in the current milestone version, 4.0.0.10485.

  • Jesse Lundberg

    First, thanks for contributing to a terrific framework! I’ve had the opportunity to test-drive a variety of them on various projects, and have found this one to be the most practical so far. I’m looking forward to using the 1.0 alpha rewrite I just pulled from GitHub in production.

    In the interim (I’m using 0.6.4), I find myself caught up in the same problem Erik described with the recent Flex 4 nightly builds, and was wondering if anyone has a fix for this issue. I’m currently frozen to the 4.0.0.1230 build because of it.

    Any suggestions would be most appreciated.

  • Jesse, thanks for your feedback but I would ask you to write this to the Swiz mailinglist so all Swiz users can follow up.