Round 2

New name for Kashi

Okay guys, we gotta rename Kashi to make it legit. Please vote:

Update: We will have a run-off vote of the top 2 during today’s code-review.

Fun With Omnigraffle

I’ve been working on diagrams for my Kashi documentation using Omnigraffle. First of all, sooooooooo much quicker than Visio. Second, here ya go:

I think the last one is the coolest looking, but it’s the more complicated option…. The first two use code-behind for the views. The last uses a map to assign a view controller to the mxml view.

How to Control a View

One of the tricks I’m working out for Kashi is deciding how to best attach a view controller to the view. The job of the “view controller” is to handle ui events and animation and move script away from mxml.

This may be something we want to leave up to each application…. projects that don’t need multiple-skins may be just fine with a more tightly-coupled view controller. On the other hand, some projects need a more flexible approach.

Approach #1: Code Behind

This is the tightest-coupled approach with the least overhead. You simply create a class that extends Canvas (or whatever container), then you create an mxml class with the base tag set to your custom class.

So, if your class is:

class Foo extends Canvas

In mxml:

<Foo xmlns="*">

You can easily call functions from the mxml like this:

<mx:Button id="myButt" click="someClick(event)" />

The reverse is a bit trickier. You have to instantiate the button in your code-behind class before you can access it…

var myButt:Button;

 Approach #2: Dependency Injection – VC into MXML

In your mxml you have a public variable vc. Ideally, this is typed to an interface, otherwise you loose code-hinting and compile-time checking. When you instantiate the mxml you do something like this:

<Foo vc="{fooVC}" /> 

One down-side here is that you refer to vc a lot in your mxml. You also have to have the fooVC easily available at the point where you instantiate Foo.

Approach #3: Dependency Injection – MXML into VC

Another way to go about it is to do something like PureMVC’s mediator approach (thanks Ben and Benjamin!). This method allows the mxml to be controller-independent. I like that. You create very Flexy (that’s a word) mxml with public bindable properties, then you could do something like this:

<Foo id="fooView" />
<FooVC view="fooView" />

Ugh. That looks ugly. The downside here is that Flex is mxml-centered, so it doesn’t make mapping this direction as clean as it could be. Optimally, we’d have a ViewControllerMap class (or something along those lines) that would do the attachments:

fooVC = new FooVC( );

This has two down-sides. First, we have to worry about timing issues… too soon and you’ll get a null error, too late and you might see a blip on the screen. Second, drilling down that path is ugly. I suppose this would work out okay, if all the views were on Application.application and we did it on initialization.

Introducing Kashi

I’ve been working on what I’m gonna call a radical branch/sect of Cairngorm. It’s currently code-named Kashi because that is the brand of cookie that I was eating at the time. The idea is to keep the basic Cairngorm pattern, but rethink the pieces.

    The Front Router

    The most significant change so far is a FrontRouter mxml class. This let’s you map events to routes. Routes consists of one or more commands.

    Not only does this fix the messy state of Cairngorm’s SequenceCommand, but it adds the ability to set properties on commands before they execute. This makes the commands a lot more portable. You can use the same command multiple times with different models to push the results into.

    Added bonus: multiple events can trigger a single command. The view layer doesn’t need to know about this. 😛

    Name-wired Dependency Injection Defaults

    Okay. I need a more catchy name for this feature. Here’s the deal: injecting an instance of a model into views and commands is the best practice… better than locking the code into a singleton (Cairngorm) or even singleton factory (our current system). But it’s annoying to specify for “fooView” that you want “fooModel”. So, Kashi figures it out for you. If you have an instance named “fooView” it will automatically look for a model instance named “fooModel”. Also, if a route is named “fooStartupRoute” it’s commands will default to use “fooModel”. These are defaults, so you can always set them manually.

    I’ll post some concrete examples with code shortly.