FAQ’s

Basics

What this faq’s is all about?

This faq's will list all questions that frequently or not can be asked about mvcExpress technical and practical details, and best practices in general. My goal will be to cover all details of programming with MVC framework and with mvcExpress in particular. I will answer to one question daily. (I have list of 72 questions already prepared) with goal to prepare full and comprehensive learning source. Also I have a plan to try and chain question is sequence to be read if you want to learn from those questions. Stay tuned.

Set up mvcExpress project

mvcExpress will work with most flash authoring tools, and and it will be set-up similarly as other ActionScript 3 projects but there are...

2 special points to remember:

  • Then you deploy - you MUST preserve metadata tags by adding -keep-as3-metadata+=Inject to your compile arguments.
mvcExpress uses custom as3 metadata tags to simplify work for you. They must be preserved then you release.
  • Then you deploy - you SHOULD remove debug compile argument, or set it to false: -define+=CONFIG::debug,false
mvcExpress uses custom compilation heavily with CONFIG::debug compile argument.
Add -define+=CONFIG::debug,true to your compile arguments and then you compile your application much more code is added in swf file to do extra work for you - check types, argument count, throw detailed errors and such. All of this should be omitted from release compilation to preserve speed of your application.
Add -define+=CONFIG::debug,false to your compile arguments then you release, or remove it.

Getting framework files:

To use framework you have to add mvcExpress to your project. You can do it by adding AS3 code files or compiled SWC to your project.
This is recommended method as it will let you define compile argument for debug/release conditional compilation.
Instead of using conditional compilation for debug/release versions you could just use SWC file compiled for that.

FlashDevelop

Very convenient tool to work with mvcExpress.
  • You don't need to add debug compile arguments - FlashDevelop does it for you.
  • You can use templates to create project and framework classes. Project and class templates - extract content to FlashDevelop 'Application Files...' folder.

Where should I start? ‘Hello World’ application?

You should start by extending ModuleCore.as class. override onInit() function. You will set-up your commands, proxies and mediators in here. [spacer size="10"] [as3 gutter="1" highlight="4,6"] package org.mvcExpress.sampleProject{ import org.mvcexpress.core.ModuleCore; public class MainModule extends ModuleCore { override protected function onInit():void { // map commands // map proxies (and services) // map modiators } } }[/as3] [spacer size="20"] in your Main.as class instantiate it and assign to a value. var module:MainModule = new MainModule(); Use the value to create yet not existing function : module.start(this); Pass thisas parameter so you could use it with framework.   [as3 gutter="1" highlight="7,8"] package org.mvcExpress.sampleProject{ import flash.display.Sprite; public class Main extends Sprite { public function Main() { var module:MainModule = new MainModule(); module.start(this); } } }[/as3] [spacer size="20"] Create (or generate) start(main:Main) function in MainModule class. Add trace("Hello mvcExpress!!!"); [spacer size="10"] [as3 gutter="1" highlight="12-14"] package org.mvcExpress.sampleProject{ import org.mvcexpress.core.ModuleCore; public class MainModule extends ModuleCore { override protected function onInit():void { // map commands // map proxies (and services) // map modiators } public function start(main:Main):void { trace("Hello mvcExpress!!!"); } } }[/as3]

How should I handle my root DisplayObject? (answer is:Mediator)

First of all you need to create mediator class that will be mediating main display object of your application. Mediators are classes that aggregate your view objects, and acts as middle man for sending messages in and out. (provides indirect communication) To do that you need:
  • extend Mediator class.
  • override onRegister and onRemove functions.
[as3 gutter="1" highlight="4,6,9"] package org.mvcExpress.sampleProject.view.main{ import org.mvcexpress.mvc.Mediator; public class MainMediator extends Mediator { override public function onRegister():void { } override public function onRemove():void { } } }[/as3] But job is not finished yet... in fact - mediator without the view object have no reason to exist! Every mediator must have declared public variable typed to view objects class and with [Inject] tag. (Tag is used to inject view into mediator automatically.) [as3 gutter="1" highlight="7,8"] package org.mvcExpress.sampleProject.view.main{ import org.mvcExpress.sampleProject.Main; import org.mvcexpress.mvc.Mediator; public class MainMediator extends Mediator { [Inject] public var view:Main; override public function onRegister():void { trace("MainMediator.onRegister called! view:" + view ); // start mediating view } override public function onRemove():void { //dispose of mediator, remove event listeners. } } }[/as3]
Then mediator class is created - next step is to pair it with view objects class by using mediatorMap.map(). mediatorMap is accessible from your MainModule objects onInit() function. [as3 gutter="1" highlight="9"] package org.mvcExpress.sampleProject{ import org.mvcexpress.core.ModuleCore; import org.mvcExpress.sampleProject.view.main.MainMediator; public class MainModule extends ModuleCore { override protected function onInit():void { // set up application mediatorMap.map(Main, MainMediator); } } }[/as3] (This work also can be moved to command.) Last step is mediating root view object... but first you need to send it to framework. The best way to do it is to create your own function start() and send root display object as parameter: [as3 gutter="1" highlight="8"] package org.mvcExpress.sampleProject{ import flash.display.Sprite; public class Main extends Sprite { public function Main() { var module:MainModule = new MainModule(); module.start(this); } } }[/as3] The last step is to initiate mediating of view object. This is done using mediatorMap.mediate(); by passing view object to it. Framework will automatically find mediator that mediates this view object and construct it. [as3 gutter="1" highlight="14"] package org.mvcExpress.sampleProject{ import org.mvcexpress.core.ModuleCore; import org.mvcExpress.sampleProject.view.main.MainMediator; public class MainModule extends ModuleCore { override protected function onInit():void { // set up application mediatorMap.map(Main, MainMediator); } public function start(main:Main):void { // mediate main view. mediatorMap.mediate(main); } } }[/as3]
  • It is a good practice to end your Mediator class names with 'Mediator'.
  • It is a good practice to put your mediator's in package 'view'. (organized to sub-folders by application features or by display object tree.)
  • Mediators can be instantiated only by framework.

I have a view object! How should I mediate it? (answer is:Mediator)

First of all you need to create mediator class. Mediators are classes that aggregate(hides) your view objects, and acts as middle man for sending messages in and out. (provides indirect communication) To create mediator you need:
  • extend Mediator class.
  • override onRegister and onRemove functions.
  • Add public variable typed to view objects class and with [Inject] tag.
[as3 gutter="1" highlight="4,6,7,9,14"] package org.mvcExpress.sampleProject.view.myTest{ import org.mvcexpress.mvc.Mediator; public class MyViewMediator extends Mediator { [Inject] public var view:MyView; override public function onRegister():void { trace("MyViewMediator.onRegister called! view:" + view ); // start mediating view } override public function onRemove():void { //dispose of mediator, remove event listeners. } } }[/as3]

Then mediator class is created - next step is to pair it with view objects class by using mediatorMap.map(). mediatorMap is accessible from your MainModule objects onInit() function. [as3 gutter="1" highlight="12"] package org.mvcExpress.sampleProject{ import org.mvcexpress.core.ModuleCore; import org.mvcExpress.sampleProject.view.main.MainMediator; import org.mvcExpress.sampleProject.view.myTest.MyView; import org.mvcExpress.sampleProject.view.myTest.MyViewMediator; public class MainModule extends ModuleCore { override protected function onInit():void { // set up application mediatorMap.map(Main, MainMediator); mediatorMap.map(MyView, MyViewMediator); } public function start(main:Main):void { // mediate main view. mediatorMap.mediate(main); } } }[/as3] (This work also can be moved to command.)
Last step is mediating you view object by using mediatorMap.mediate();. The best place for this job is parent-mediator - mediator that mediates the parent view. Lets say MainMediator wants to add instance of MyView to view it is mediating. MainMediator will then do only adding(removing) and mediating(unmediating) work for our instance of MyView. State of myView object have to be handled not by MainMediator, thats work of MyViewMediator. Then you mediatorMap.mediate(); your view object - mediator that paired with this object is automatically created, and view object is injected into it. [as3 gutter="1" highlight="14,15,16,20,21"] package org.mvcExpress.sampleProject.view.main{ import org.mvcExpress.sampleProject.Main; import org.mvcexpress.mvc.Mediator; import org.mvcExpress.sampleProject.view.myTest.MyView; public class MainMediator extends Mediator { [Inject] public var view:Main; var myView:MyView; override public function onRegister():void { myView = new MyView(); view.addChild(myView); mediatorMap.mediate(myView); } override public function onRemove():void { view.removeChild(myView); mediatorMap.unmediate(myView); } } } }[/as3] (There are couple of strategies how to add and mediate your view object by parent-mediator, or commands. But that is another question...)
  • It is a good practice to end your mediator class names with 'Mediator'.
  • It is a good practice to put your mediator's in package 'view'. (organized to sub-folders by application features or by display object tree.)
  • Mediators can be instantiated only by framework.

How should I handle my data? (answer is:Proxy)

First of all you need to create proxy class. Proxies are classes that aggregate(hides) your data objects, and provides interface to manipulate that data. (provides direct communication) To create proxy you need:
  • extend Proxy class.
  • override onRegister and onRemove functions.
    • [as3 gutter="1" highlight="4,10,14"] package org.mvcExpress.sampleProject.model.test{ import org.mvcexpress.mvc.Proxy; public class TestProxy extends Proxy { public function TestProxy() { // handle constructor parameters if any. } override protected function onRegister():void { // init proxy data } override protected function onRemove():void { // dispose of proxy data } } }[/as3] Both constructor function and onRegister() function can be used to initiate your proxy data. But using onRegister() recommended because it is executed after proxy is registered with framework(and all dependencies are injected).
      Then you have your proxy created - next step is to register it with framework using proxyMap.map(new TestProxy()); mvcExpress uses proxy class name to map object with framework. proxyMap is accessible from your MainModule objects onInit() function. [as3 gutter="1" highlight="9"] package org.mvcExpress.sampleProject{ import org.mvcexpress.core.ModuleCore; import org.mvcExpress.sampleProject.model.test.TestProxy; public class MainModule extends ModuleCore { override protected function onInit():void { // set up application proxyMap.map(new TestProxy()); } public function start(main:Main):void { } } }[/as3] (This work also can be moved to command.)
      Then proxy class is registered it can be injected into your commands, mediators and other proxies. To do that you need to declare public variable typed to proxy class, and add [Inject] metadata-tag. [as3 gutter="1" highlight="7,8"] package org.mvcExpress.sampleProject.controler.test{ import org.mvcexpress.mvc.Command; import org.mvcExpress.sampleProject.model.test.TestProxy; public class TestCommand extends Command { [Inject] public var testProxy:TestProxy; public function execute(blank:Object):void { trace( "TestCommand.execute :: testProxy: " + testProxy ); } } }[/as3]
      • It is a good practice to end your proxy class names with 'Proxy'.
      • It is a good practice to put your proxies in package 'model'. (organized to sub-folders by application features.)

Creating simple command? (Command)

Commands are used to handle application business logic. Look at them as sophisticated functions! To create one you need to do 3 things:
  1. extend Command class
  2. create public function execute()
  3. create one and only one parameter in execute() function. (of any type you need, or if you don't need any parameters put dummy parameter. (for example: blank:Object));
Your command will look like this: [as3 gutter="1" highlight="4,9"] package com.mindScriptAct.sample.controler.test{ import org.mvcexpress.mvc.Command; public class TestCommand extends Command { //[Inject] //public var myProxy:MyProxy; public function execute(params:Object):void { } } }[/as3]
  • It is a good practice to end your Command class names with 'Command'.
  • It is a good practice to put your command's in package 'controller'. (organized to sub-folders by application features or by command purpose.)
  • Commands can be instantiated only by framework.

How commands are executed? (answer is:Command)

You can execute commands in 2 ways: directly and indirectly.
  • You can execute commands directly using commandMap object:
[as3] commandMap.execute(ClassOfCommand, new ParamVO()); [/as3] Second parameter is optional and will be passed to execute function as parameter. commandMap is accessible from your Module classes and other Command classes.
  • To execute commands indirectly you will need to use framework messages:
First you need to map Cammand class to message string. [as3] commandMap.map("messageName", ClassOfCommand); [/as3] Then this is done, the only thing you need to do to get your Command executed - send a message. (Second parameter is optional and will be passed to execute function as parameter.) [as3] sendMessage("messageName", new ParamVO()); [/as3] You can send messages from all framework actors : Module, Cammand, Proxy, Mediator. It's good idea to store message string - "messageName" in a constant. It is better practice to use messages to execute your command in almost all cases. But there is some exceptions, for example if you don't plan to reuse your command, or your command is tightly bundled with current command(or module) in the way that it does not make sense to use outside of it.

Communication

There should I put message string’s?

There are couple of strategies regarding of placement of message string constants:
  • Divide all message constants to classes by core purpose.
All message constants are divided in 3 classes:
  1. Business logic messages and anything that does not fit #2 and #3. (Msg.as or Note.as)
  2. Data change messages. (DataMsg.as or DataNote.as)
  3. View interaction messages. (ViewMsg.as or ViewNote.as)
This is approach I use, it will simplify message constant management, and will help avoid too bloated classes a bit. There will be cases then some messages will have more then one purpose(for instance sent by view object and command), but then just try to identify main purpose .
  • Single class to hold them all
This will centralize message constant management in one class. Someone use main application module class for it, some create dedicated class. Downside of this approach is that in big application you will end up having huge list of constants in one class that will be hard to navigate.
  • Main sender is the constant holder
This strategy sounds like good idea, as it will keep message constants there they intuitively belong - main object that sends it. But then every time you will want to use that constant outside of main sender you will have to remember and import that class. In the long run it will waste time.
  • Dont use constants, leave it as string literals
I don't consider this as an option. It's hard to remember such message, its easy to miss spell, and hard to rename. You will waste much time and put your application under not needed risk if you go tihs path.

Troubleshooting

The extra debug error checking and warning does not work for me!

To make mvcExpress fast then you release, yet effective for debugging while you work with it - conditional compilation is used. You can enable canditional compilation by adding : -define=CONFIG::debug,true to you compile argument if you want mvcExpress to do extra work on checking errors. -define=CONFIG::debug,false to you compile argument if you want mvcExpress to run faster, and without extra error checking. Links:

Why if I run release build it breaks or gives me white screen? (Then I compile in debug mode it works fine!)

  • If you compile with flex 4.1 or less - you need to add -keep-as3-metadata+=Inject to compile options.

I try to inject proxy, but all I get is null object error!

  • Check if your [Inject] metadata is not misspelling. (Check letter case.)
  • Check if your variable is public. (not private or protected)

Can i use Flash IDE with mvcExpres? If I try – project fails.

It is possible to use Flash IDE with mvcExprss. After adding source and library path's for you code you need to do 2 extra steps:
  • Add CONFIG::debug Config constant and set it to true or false.(use false for deploy, and true for debugging.)
You can set it in MENU::File:Publish settings... ->'Flash' TAB -> Script: 'Settings...'  -> 'Config constants' TAB
  • Export to SWC, even if you will not use it. (Then you export to SWC flash IDE preserves metadata-tags in your code . [Inject] metadata tag essential to mvcExpress is lost if you don't export to SWC!)
You can do this by enabling 'Export SWC' check-box  in  MENU::File:Publish settings... ->'Flash' TAB
 

15 thoughts on “FAQ’s”

  1. hi,Deril
    in the FAQ of ‘I have a view object! How should I mediate it? (Mediator)’,
    you mentioned:
    ‘Last step is mediating you view object by using mediatorMap.mediate();.
    The best place for this job is parent-mediator – mediator that mediates the parent view.’

    If one view’s parent doesn’t have a mediator, how to mediate this view?
    I don’t want to create a lot of mediator whose responsiblity only are mediating sub-view, especially the parent of the parent of ….parent of this view all needn’t have a mediator, because they don’t care of any bussines logical and just focusing UI logical.
    how to I avoid those boilerplate codes?

    thanks

  2. Hi Raimundas, I would be interested in using mvcExpress in a commercial project where performance is an issue. Could you tell me please under what license it is released?
    thanks

    1. Hi,

      The MIT License.

      you can do with code whatever you want, as long as Mit license note stays with the code. (you don’t need your project to be under Mit, only mvcExpress files);

      Have fun with mvcExpress!

  3. Hi,

    First of all thank you to share this framework with the community.

    I was looking the last weeks to StarlingMVC and today I have discovered your framework. It looks very very interesting.

    I’m just a bit disappointed, don’t understand, why to mediate a view it has to be set up in the view parent mediator. It’s sounds like we have to reproduce the view hierarchy to mediate all the view and let each view parent how its children is mediate.

    I don’t know if it is a good idea neither how it is achieve, but in StarlingMVC there is one thing I find interesting and make thing easier, you bind a Mediator to a View and when the View is added to the display list the View will be automatically injected in the Mediator. I found this way very flexible and more loose coople.

    What to do you think about that ? May be it is not a good approach but I’m enough an expert to judge, so I ask your opinion.

    Again, thank you !

    1. Hi,

      Interesting question.

      I understand appeal of automatic mediation, it sounds nice, but it is awful in practice! Every display object that lands on stage must get event handler, and all that just to avoid writing single simple line per mediator? Its not like there will be hundreds of lines saved this way, 20-30 most likely.

      Automatic mediation goes directly against mvcExpress principles:

      First of all it hurts performance. A lot! Unless you are writing really small application automatic mediation is not even an option.
      Of course, I could make it optional, like robotlegs did, but even then it will most likely add some overhead, in the end I decided to focus on more important things and removed this question from the table altogether.

      Another point is more of a personal preference then strong argument – I like explicit mediation, I like that then I read mediator class, I see exactly what it does, and there is no hidden ‘magic’ happening in the background.

      As I mainly focus on medium-large application, automatic mediation never was an option to me. And I decided not to use this approach even with small application, to avoid developing bad programming habits.

      I will think about it, maybe it is possible to add this feature as an option, without hurting current performance if it’s disabled. But first.. I want to finish couple of more important features. (JSON class descriptions instead of XML, explore use of workers in framework.)

      So again… I understand appeal of this feature, but performance costs are just too high, even for applications that can bare it. And then you write mediation explicitly you are more ‘in touch’ with your application.

      Regarding loose coupling – I understand your point. It would be easier to change the view, without the need to care about how container mediator handles it, but you have to sacrifice some convenience for application performance.

      Thank for the question.

      I will add ticket in gitHub to prototype it.

  4. Thank for your answer and the explanation. I understand your point of you and it makes sense for me.

    My question was more about the loose coupling aspect than saving line of code. Make me feel a bit weird to have a Mediator coupled to the view is mediating and the child views that need to be mediated.

    You said the Main Mediator is the best place to create a child view and call the mediate function, but is there another way ? What I have in my mind is to describe my view in an XML file and for each view set up the Mediator class to use. So I can parse the XLM, build all view and add child them to the right parent view and then start the mediation. So i’t more about to be able to configure Views and Mediator in an XML file more than an Action script class.

    Something like (just an example I made up right now, not something 100% real)

    I don’t know if I’m clear but I hope so. Englis is not my best skill ;-) Do you think it’s a good idea to configure all in an XML file or do you think it’s better to explicitly do this in ActionScript file ?

    Again, thank you ! This framework looks interesting and really make me think. I’m about to start a new project based on Starling and I’m looking for a solution to build it a more clean and modular way.

    1. That is very interesting point! I remember reading about it somewhere.

      I guess you have to solve 2 questions…
      1 – how to define your views conveniently.
      2 – how to handle life cycle…

      To be honest… I am not sure how to implement it. Never thought about it…

      It sounds like nice idea for extension.
      I will research it. Thanks!

  5. Hi. I’m testing your framework together with the Starling. Overall, it looks very promising. I do not have much experience with MVC patter and I miss the tutorial, which would explain step by step how to create a fully working application with a sample model, view and controller. In the section Learn mvcExpress is “mvcExpress training course: part1″, but it is only an introduction explaining the principles of the MVC pattern. Examples are already done, so I can’t easy and fast find what classes to make at first and what are relations between them. But they are very helpfull :)

    I also noticed that very often there is a word “Then” used instead of “When” in comments and your texts. So it’s sometimes hard to get point of sentence…

    1. Hi,
      glad you like this framework! I am sorry for lack of good tutorial… now then more and more people are missing it I have good incentive to get back to it.

      If you get stuck, just drop a question in forum.

      (And, I will check my “Then” usage… thanks!)

  6. Hello Deril and thanks so much for your great effort!
    Well i am a flex/actionscript beginner and i am working in a medium project(not for gaming but Enterprise business )using flex/actionscript and i wanted to integrate ‘MvcExpress’ which is looking so promissing ;=)
    So i just wanted to ask you some questions if you don’t mind ;=)
    1- Is it possible and easy enough to use ‘MvcExpress’ on flex ,itemRendrer and the holl stuff because i noticed that all your examples are done using ActionScript projects(Exteding Sprite and so on).
    2-Pleaaaase ! Try to make a short record showing us the basic workflow using ‘MvcExpress’ ; I think videos are the best manner to explain a lot of thinks in place of writing textual and long tutorials

    1. Hello,
      Thanks for using mvcExpress!

      mvcExpress works well with flex, and I did couple of flex project with it.
      I would recommend using FlexMediator extension, as it simplifies workflow.

      I was planing to do video tutorial series on mvcExpress… but sadly never found time for it.
      I will consider it.. but can’t promise anything at this point.

      Have fun with mvcExpress!

Leave a Reply to Deril Cancel reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

simplest and fastest ActionScript 3 MVC framework