Futurescale, Inc. PureMVC Home

The PureMVC Framework Code at the Speed of Thought


Over 10 years of community discussion and knowledge are maintained here as a read-only archive.

New discussions should be taken up in issues on the appropriate projects at https://github.com/PureMVC

Show Posts

* | |

  Show Posts
Pages: [1] 2
1  Announcements and General Discussion / General Discussion / Re: Facade.removeCore() throws error using FB 4.x framework on: August 19, 2010, 06:30:53
Thanks for all the help and advice Cliff.  I spent the end of my work day and part of my evening at home implementing what you just described in a current project I am working on.  Everything seems to load and unload nicely, memory size drops on unload of module and core, and the KapIt console is confirming that the mediators and proxies are being removed as they should.

Many thanks to your for not only the framework, but taking time to support our issues and questions in the forum.  Time-wise, I know that can be a real undertaking, so I just wanted you to know I really appreciate it.

Thanks again!

TJ
2  Announcements and General Discussion / General Discussion / Re: Facade.removeCore() throws error using FB 4.x framework on: August 17, 2010, 12:29:22
When you want to share constants between various modules and the shell, you should create a separate library to put those constant definitions in, and then include the library in the shell and any modules that need it.

OK.  So I would like to use the library approach, but not sure I understand what you mean by 'library'.  Would the below code be considered implementation of suggested 'library'?

:
package common
{
/**
* ...
* @author TJ Jones
*/
public class ModuleLibrary
{
public static const MY_MODULE:String = 'my_module';
public static const MODULE_A:String = 'module_b';
public static const MODULE_B:String = 'module_c';

public function ModuleLibrary()
{

}

}

}

And thus the Facade.getInstance() would then be passed the correct constant accordingly?

:
// somewhere in a module initialization....
MyModuleFacade.getInstance(ModuleLibrary.MY_MODULE).startup(this);

I'm all about adhering to best practices whenever possible or suggested, so I'd like to follow your library advice.

TJ
3  Announcements and General Discussion / General Discussion / Re: Facade.removeCore() throws error using FB 4.x framework on: August 16, 2010, 10:18:45
OK, so I built a project to test the issue.  I didn't include pipes, but just bubbled an event on the display to keep the code as simple as possible.

The only addition to the code is the KapIt console for monitoring the framework. Shift+alt+Click will open the console.

To my suprise, initially, everything worked just fine.  However, it wasn't until I started messing with the static Facade.hasCore() that I saw the UIComponent error again.  With a little experimentation, I was able to find what conditions would cause the error using the method and which would work as expected.

What I found was  if I test for the module core existence from the shell (calling Facade.hasCore(MyModule.NAME) on Shell.mxml line 53, the UIComponent class throws the error.

:
private function loadModule(e:MouseEvent):void
{
if (moduleContainer.numElements == 0)
{
// Testing to see if core exists here causes UIComponent error
trace("Module Core Exists:", Facade.hasCore(MyModule.NAME))
moduleInfo = ModuleManager.getModule("module/MyModule.swf");
moduleInfo.addEventListener(ModuleEvent.READY, moduleReadyHandler);
moduleInfo.load();
}
}

However, if I performed the same hasCore test from within the module on line 27 - trace(Facade.hasCore(NAME)), then no error is thrown:

:
public static const NAME:String = 'MyModule';

private function init():void
{
// testing to see if the core exists here works fine.
trace(Facade.hasCore(NAME));
ModuleFacade.getInstance(NAME).startup(this);
}

So, here is where my lack of computer sciene knowledge may be my problem:

Since Facade.hasCore() is a static function, then I would personally think it's not scope specific and could be called from anywhere in the application.  However, it would appear that I am observing a scope specific behavior in that I can't test for the existence of a module core from the shell.

Could someone clarify what is suppose to happen and is the error on my end from lack of understanding or something else?

I posted the project on my server.  It's a zip, but just extract and you will find the .fxp inside and use File->Import to bring it into your workbench.

http://67.239.69.29/Testing/ModuleTest.zip

Thanks!
4  Announcements and General Discussion / General Discussion / Re: Facade.removeCore() throws error using FB 4.x framework on: August 16, 2010, 08:12:01
Hey Cliff,

Can you try running the GarbageCollectingPipes project example in Flex 4.x?  That project throws the same error as mine.

I have some time today, so I am going to build a minimalist module project and see what I find.  I will post it as soon as I have something to report.
5  Announcements and General Discussion / General Discussion / Facade.removeCore() throws error using FB 4.x framework on: August 14, 2010, 03:21:43
Hey guys,

I have been working with this issue for several hours and I have found that calling the static removeCore() causes an error on line 10632 of UIComponent.

To catch you up with what I have done, I build an app with a Module using multicore from the ground up. Everything works fine with creating the module through the module manager and the core if I never plan to remove the module's core.  However, what is interesting is once I place the removal call in my code (it doesn't have to get called) then I get the error. (And the error is thrown when the module is attached to the display... weird).

So I downloaded the GarbageCollectingPipes example and found the same error being thrown, but commenting out the remove core in the command does not have the same effect.  I'm now playing with that project to see if I can isolate what is triggering the error.

Does anyone have a clue as to a workaround for this?  I don't wish to downgrade my project to 3.x. 


Thanks!
6  Announcements and General Discussion / General Discussion / Re: A mediator for every display item? on: July 26, 2010, 12:34:42
Hey Cliff,

Are you suggesting a mediator that listens to the stage for add item events to bubble and then inspecting the targets to see if they are classes requiring mediator construction and wire-up?
7  Announcements and General Discussion / General Discussion / Re: URGENT: How can I get the mediator to listen to all Notifications. on: July 23, 2010, 02:07:47
Dont know if this would help, but KapIT has a nice little PureMVCControlPanel which is nice for debugging.  If it's a matter of finding what notification is causing the problem, this may help as it tracks everything going on in the MVC part of the app.

Here is the URLhttp://lab.kapit.fr/display/puremvcconsole/PureMVC+Console

8  Announcements and General Discussion / General Discussion / Re: A mediator for every display item? on: July 23, 2010, 02:01:13
I'd like to add that your working condition has alot to do with how you would setup your mediators and the entire facade for that matter.  I have the unfortunate displeasure of working at a company where my projects are 'design by committee' with no documentation presented to me, unqualified people making requests for changes and new features whenever they want, etc...  PureMVC has been my code equivalent to LEGOs. 

I have adopted my own custom practice for communication between components and mediators that has been very handy for my situation.  Quite often I start off with a component and mediator pair, but after a Monday meeting, I may come away with over a dozen changes / added features.  It's quite ridiculous. So, as I get to implementing the block outs for the view, I look through the component and see what needs to be it's own component based on what things are similar, and cut that xml and paste it into a new component and setup a new mediator.

So, here is what I do that is specific to my setup that has helped me in this crazy world of flux that I spend 40 hours a week in:

- Components are responsible for creation and destruction of their mediators

This really helps when I use view states and the includeIn or excludeFrom tag for a component (seems to happen alot latey as I think these guys are seeing how far they can push me.
:
// some example code
private function init():void
{
_facade = MainFacade.getInstance(Main.NAME);
_facade.registerMediator(new AdminMediator(this));

}

- Make sure you have proxies for your data.  You wont get very far with the above if you dont - Poof! Gone the minute the state changes...

- Custom payload-able ViewEvent that is dispatched to the mediator from the component.

This is how the component messages it's mediator.  The event has no static constants defined.  It passes constants defined in the component:

:
// defined constants
public static const INSERT_NEW_TESTIMONIAL:String = 'insert_new_testimonial';
public static const EDIT_CURRENT_TESTIMONIAL:String = 'edit_current_testimonial';


// and an example of the dispatch. This one has a payload
dispatchEvent(new ViewEvent(EDIT_CURRENT_TESTIMONIAL, editItem));

Then the mediator has registered listeners in it's constructor
:
public function AdminMediator(viewComponent:Object)
{
super(NAME, viewComponent);
// No references to the facade are allowed in the constructor.
view.addEventListener(AdminView.INSERT_NEW_TESTIMONIAL, viewEventHandler);
view.addEventListener(AdminView.EDIT_CURRENT_TESTIMONIAL, viewEventHandler);
}

and then my viewEventHandler is very similar to the handleNotifications in that it uses a switch statement:

:
private function viewEventHandler(e:ViewEvent):void
{
switch (e.type)
{
case AdminView.INSERT_NEW_TESTIMONIAL:
sendNotification(MainFacade.INSERT_NEW_TESTIMONIAL, e.data);
break;

case AdminView.EDIT_CURRENT_TESTIMONIAL:
sendNotification(MainFacade.EDIT_CURRENT_TESTIMONIAL, e.data);
break;
}
}

As a result, I end up with very consistent mediators in design and refactoring to add a new mediator is quite painless with the help of copy/paste to move over some case conditions and the old find and replace for updating the view names.  And yes, the necessary constants are moved to the new component as well.

Mediator in 5 seconds...

Until some serious support for templates becomes available in FB, I use FlashDevelop to create my actors. It's a little clunky having 2 IDEs open, but it saves time.

If you have FD, you are welcome to my mediator template.  Here is the code below for the fdt file:

:
package $(Package) $(CSLB){
import org.puremvc.as3.multicore.interfaces.IMediator;
import org.puremvc.as3.multicore.interfaces.INotification;
import org.puremvc.as3.multicore.patterns.mediator.Mediator;
import $(Package).*;

/**
* ... PureMVC - Mediator Class Multi core
*
*/
public class $(FileName) extends Mediator implements IMediator
{
// Cannonical name of the Mediator
public static const NAME:String = "$(FileName)";

public function $(FileName)(viewComponent:Object)
{
super(NAME, viewComponent);
// No references to the facade are allowed in the constructor.
}

override public function onRegister () : void
{
// Make any calls to the facade here:
}

override public function getMediatorName():String
{
return $(FileName).NAME;
}
       
override public function listNotificationInterests():Array
{
return [];
}

override public function handleNotification(note:INotification):void
{
switch (note.getName())
{
default:
break;
}
}

/* IMPORT view class and View event
private function viewEventHandler(e:ViewEvent):void
{
switch (e.type)
{
default:
break;
}
}

public function get view(): // add View Class
{
return viewComponent as // add View Class
}
*/
}
}

and here's my view event.  I have a common.events package in my source.
:
package common.events
{
import flash.events.Event;

public class ViewEvent extends Event
{
public var data:Object;

public function ViewEvent(type:String, data:Object=null, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
this.data = data;
}

override public function clone() : Event
{
return new ViewEvent(this.type, this.data, this.bubbles, this.cancelable);
}


override public function toString():String
{
return formatToString("ViewEvent", "type", "bubbles", "cancelable", "eventPhase", "data");
}
}
}


So yeah... My code is like LEGOs... or should I say Cliff-Blocks?  ;)  I don't know that this would be considered a 'best practice' by any means, but it does allow me to make fairly drastic changes quickly and without bugs popping up provided I moved all the parts that were related to the new components and mediators.

I'd actually be interested to see how others are handling changes in design.... Provided they are plagued with 'Design by Committee' like I am.

TJ
9  Announcements and General Discussion / General Discussion / Re: ?? Best Practice Flash Builder 4 Value Objects and View / framework separation on: February 01, 2010, 07:04:30
Hey Cliff,

Thanks for your response.  I will take a look at the employee example this morning.

TJ
10  Announcements and General Discussion / General Discussion / ?? Best Practice Flash Builder 4 Value Objects and View / framework separation on: January 29, 2010, 02:25:35
I've been doing some developing in Flash Builder 4 Beta.  Seems from what I have read and implemented in some projects I am playing with, the new fx:Declarations tag is where you would declare your VO's along with other misc non visual elements. 

So I read on a blog about '10 Best Practices for PureMVC' http://www.websector.de/blog/2007/12/25/10-tips-for-working-with-puremvc/ that VO's, not being actors of the frame work are a good way to react to changes in the model without breaking the rules....   

After reading this and trying to conceptualize a bit of ambiguity from that post it got me thinking about a possible solution to allow the view to react to model updates directly vs waiting on the proxy to send a notification, a mediator or command to process it, and finally update the view accordingly (possible not breaking the rules as the article so elegantly expresses?).

Here's my thought:

In your vo package, define a bindable Value Object class

In your view, declare an instance of the vo in the fx:Declarations tag.  Then bind whatever controls to it, it's properties, etc...

On the proxy, create a property of the VO and have the responder cast the result to the VO property.  Create your getter/setters for it as well.

In the mediator, depending on your style, either access the proxy through the facade and set the VO in the view to the VO on the proxy, or send a notification and let a command do it... Something like:
:
mediator.myView.myVo = proxy.myVo;


So, being of curious mind, I tried this and it did work.  The view's declared VO was set before the data was ever received from the server and I saw the control populate after the data was received.  I did not have to send a notification and notifiy a mediator or command of the data received. 

Would this be 'breaking the rules'?  I do have a couple of scenarios in my projects where an ArrayCollection of data objects may get updated by a new record or a record deleted.  It would be nice to have this wireup between databinding of the control and the proxy just to save some time and code, but at the same time I would not want to paint myself into a corner down the road. 

Any thoughts or advice?

I strip down my example and post the code if I can make time this afternoon.
11  PureMVC Manifold / Demos and Utils / Re: State Machine and ViewState example - Flex 3.4 on: December 16, 2009, 03:15:30
Update:

It makes even more sense now as to why one should leave the viewState for the view and the FSM is for the logic/Facade. I am working on a project in Flash Builder Beta 2, and the new syntax for the viewstate makes everything easy to manage within the view (and obvious as to what it's doing). So now I understand more clearly the implementation, thus keeping the view and mediator as independent as possible.

 Here is some view mxml utilizing the new viewState syntax:
:
<s:HGroup gap="5" width="100%">
<mx:ComboBox id="category" width="430" labelField="NAME_VCC"
enabled.BASE="false" enabled.INIT="false"
dataProvider="{dpCategories}" selectedIndex.BASE="-1" />
<s:Button id="btnUpload" label="Upload Movie" width="100%" label.EDIT="Update Selection"
  enabled="false" enabled.INIT="false" enabled.BASE="false"
  click="uploadRequestHandler(event);" />
<s:Button id="btnCancel" label="Cancel" width="100%" click="btnCancelHandler(event);"
  enabled.BASE="false" enabled.INIT="false"/>
</s:HGroup>

My viewStates:
:
<s:states>
<s:State id="stInit" name="INIT" />
<s:State id="stBase" name="BASE" />
<s:State id="stUpload" name="UPLOAD"/>
<s:State id="stEdit" name="EDIT"/>
</s:states>


Actions and states for the FSM:
:
// actions for the state machine
public static const ACTION_GOTO_EDIT_STATE:String = '/action/goToEditState';
public static const ACTION_GOTO_UPLOAD_STATE:String = '/action/goToUploadState';
public static const ACTION_BROWSE_FOR_FILE:String = '/action/browseForFile';
public static const ACTION_SELECT_FILE:String = '/action/selectFile';
public static const ACTION_CANCEL_SELECT_FILE:String = '/action/cancelSelectFile';
public static const ACTION_CHECK_FLV_EXISTS:String = '/action/checkFlvExists';
public static const ACTION_FTP_UPLOAD_FLV:String = '/action/ftpUploadFlv';

// states for the state machine
public static const STATE_IDLE:String = '/state/idle';
public static const STATE_UPLOAD:String = '/state/upload';
public static const STATE_EDIT:String = '/state/edit';
public static const STATE_FILE_REF_OPEN:String = '/state/fileRefOpen';
public static const STATE_FILE_EXISTS_CHECK:String = '/state/fileExistsCheck';
public static const STATE_FTP_TRANSFER:String = '/state/ftpTransfer';

And lastly, the only vars in the view which my mediator is aware of:
:
[Bindable]
public var dpFlvList:ArrayCollection;
[Bindable]
public var dpCategories:Object;
[Bindable]
public var flvDataObject:Object;

I now have alot less code overall, and my mediator is much smaller than before. 

So now I see my error of the original example I posted in which I was using the FSM/Facade to control the viewstate through the Mediator - Bad idea.

12  PureMVC Manifold / Demos and Utils / Re: State Machine and ViewState example - Flex 3.4 on: December 16, 2009, 10:21:09
Hey Cliff,

Thanks so much for taking the time to explain that in more detail. You just created extra work for me LOL!  Good thing is I got it approved through my boss. They know I strive to write good code and allow me freedoms for improvement and education during a development process. 

I broke off to a branch of the current project I am working on and I am in the process of rewiring according to your advice.  My mediator has fallen victim to being a puppetier and I want to fix that.

The project is a media library administration app for a company website.  The admin is able to FTP flv, wmv, mp3, images, pdfs, etc., to the site's library and entries are logged to corresponding tables in a database.  I just began a couple of days ago, so I'm not to far and it's a good time to rework. 

I'll post an update with any relevant issues in the code here for feedback or solutions to help others as I they become available.

Thanks again for your time in posting your response.

In the mean time, if anything else helpful comes to mind, please post and I will read it immediately.
13  PureMVC Manifold / Demos and Utils / Re: State Machine and ViewState example - Flex 3.4 on: December 15, 2009, 09:41:25
I see your point, but I'm not sure how one could implement a relationship between a mediator and a view without some form of tight coupling.

Example:  You have a view with various components (buttons, lists, etc) and you define the event handlers for those components in the script block to send custom event messages, etc.  This is all fine and dandy, but there are still to hurdles I see that prevent a loosely coupled design:

1 - Bridging between the Events on the display and messages in the facade.  One would still have to register an event listener for the view within the mediator for events dispatched by the view (user clicks and what not)...

2 - Pushing dataproviders into the view.  Say a collection of items from a proxy for a list control. Proxy.SUCCESS message to mediator (or command and then to mediator depending on design).  However, once you are at the mediator, you still need to access the list in the view through an implicet getter or similar to access the list and pass it the data collection.

So Cliff, (or anyone else for that matter) please set me straight if I have completely missed something here.  I carry no degrees or education in computer science. I'm self taught and my desire is to write solid and maintainable code.  Therefore, is there a way to truely separate out the coupling completely or is there an acceptable level or coupling contamination between the view and the mediator that I should not be concerned with? I believe I am in need of a little schooling...

I am merely 'Grasshopper', but one day I hope to 'snatch the pebble' from your hand...  ;D
14  PureMVC Manifold / Demos and Utils / State Machine and ViewState example - Flex 3.4 on: December 14, 2009, 02:23:29
Hello,

I just started playing around with the FSM StateMachine utility and in my process of getting a grasp on how it works through viewing other examples, I created my own example which utilizes 1 button to cycle through states with 1 Action message.  I've also setup the app to use a flex ViewState in conjunction with the FSM.  The purpose here is separate out the different parts of the application as loosly as possible.  In my comments you will find some ideas on a more complex proxy than the initial included proxy.  Also in the Injector command I explain in more detail a concept for state cycling via 1 action command. 

The methods here behind my madness are to keep the view as uncoupled as possible - specifically the mxml file(s).  Personally, I like to avoid actionscript in the mxml file and directly binding functions in the event attributes.  I'd rather register listeners in the mediator and handle as much of it as possible there.  So other than the Facade setup, and 1 dispatcher function (left there for simplicity), the rest of the AS code is in AS files.

If anyone has an example of a better or even different way of tying the FSM to ViewStates, I'd love to see them and I am completely open to suggestions. 

This simple example is a result of me examining the StopWatch example and then building from the ground up based on the concepts found within the StopWatch project.  So it should be fairly familiar in general for much of the core.

Enjoy and I look forward to any comments/responses.

TJ
15  PureMVC Manifold / MultiCore Version / Re: Need Pipes help. I think mine are clogged on: October 14, 2009, 12:40:20
Yup. My pipes were clogged.  I found the issue.  In my override of the module's junction mediator listNotificationInterests() method, I did not call the super's list and append to it with my notifications, thus the JunctionMediator.ACCEPT_INPUT_PIPE  and JunctionMediator.ACCEPT_OUTPUT_PIPE were no longer in the list.

Hopefully this little tid-bit will help someone else if they run into the same issue.

Thanks!
Pages: [1] 2