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

Pages: [1]
Print
Author Topic: Do I need proxies only to consume remote data  (Read 15624 times)
vladakg85
Full Member
***
Posts: 22


View Profile Email
« on: April 19, 2009, 04:39:19 »

Hello, my first post here wow ;)

I'm new to puremvc, and I wan't to learn it, I started today and got one question.
I wan't to make simple hello world AIR application, I make main.mxml, one component that hold panel with my controls etc. Now I'm building mediator, my question is: If I want to hardcode my Hello sample (Hello, {name}) do I need proxy? As I understand proxie retrive data from remote source so IMHO I need to put my hello logic only in command, right?

Sory for bad english. junior ;)
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #1 on: April 19, 2009, 06:32:20 »

You'll want to use a Proxy to retrieve the data and then send it to the Mediator via Notification. The Mediator will set the data on the view component and the component will bind locally to that data. Have a look at the Employee Admin Flex demo for how to do this binding in the view. It does not retrieve the data from a remote service, it simply creates it, but the concept of getting it to the view and binding there is the same.

-=Cliff>
Logged
vladakg85
Full Member
***
Posts: 22


View Profile Email
« Reply #2 on: April 19, 2009, 10:07:47 »

Hi, Cliff thanks for replay, but I become I little scared when I saw code in Employee Admin application, and everything became so confusing? :( Here what I done so far, I don't know is this good, but anyway I stack here for some reason :(

SampleProject.mxml
:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
xmlns:view = "sampleApplication.view.component.*"
creationComplete="facade.startup(this)">
<mx:Script>
<![CDATA[
private var facade:ApplicationFacade = ApplicationFacade.getInstance();
]]>
</mx:Script>
<mx:VBox horizontalAlign="center" verticalAlign="middle">
<view:HelloPanel id="hello" width = "300" height="300" horizontalAlign="center" verticalAlign="middle"/>
</mx:VBox>
</mx:Application>

ApplicationFacade.as
:
package
{
import org.puremvc.as3.interfaces.IFacade;
import org.puremvc.as3.patterns.facade.Facade;

import sampleApplication.controller.StartupCommand;

public class ApplicationFacade extends Facade implements IFacade
{
public static const STARTUP:String = "startup";
public static const HELLO_OK_CLICKED:String = "helloOkClicked";


public static function getInstance():ApplicationFacade
{
if (instance == null)
{
instance = new ApplicationFacade();
}
return instance as ApplicationFacade;
}

public function startup(app:Object):void
{
sendNotification(STARTUP, app);
}

override protected function initializeController():void
{
super.initializeController();

registerCommand(STARTUP, StartupCommand);
}

}
}

HelloPanel.mxml
:
<?xml version="1.0" encoding="utf-8"?>
<mx:Panel xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"  title="test">
<mx:Button id="btnOk" x="44.5" y="40" label="ok" width="78"/>
<mx:TextInput id="txName" x="7" y="10"/>

</mx:Panel>


HelloPanelMediator.as
:
package sampleApplication.view
{
import flash.events.Event;
import flash.events.MouseEvent;

import org.puremvc.as3.interfaces.IMediator;
import org.puremvc.as3.interfaces.INotification;
import org.puremvc.as3.patterns.mediator.Mediator;

import sampleApplication.controller.MakeHelloCommand;
import sampleApplication.view.component.HelloPanel;

public class HelloPanelMediator extends Mediator implements IMediator
{
public static const NAME:String="HelloPanelMediator";

public function HelloPanelMediator(viewComponent:Object=null)
{
super(NAME, viewComponent);
}

override public function onRegister():void
{
helloPanel.btnOk.addEventListener(MouseEvent.CLICK, onOkClick);
}

private function onOkClick(evt:Event):void
{
sendNotification(MakeHelloCommand.CMD_MAKE_HELLO, helloPanel.txName.text);
}

override public function listNotificationInterests():Array
{
return [MakeHelloCommand.CMD_MAKE_HELLO];
}

override public function handleNotification(notification:INotification):void
{
switch (notification.getName())
{
case MakeHelloCommand.CMD_MAKE_HELLO:

break;
}
}

private function get helloPanel():HelloPanel
{
return viewComponent as HelloPanel;
}

}
}
StartupCommand.as
:
package sampleApplication.controller
{
import org.puremvc.as3.interfaces.ICommand;
import org.puremvc.as3.interfaces.INotification;
import org.puremvc.as3.patterns.command.SimpleCommand;

import sampleApplication.model.HelloProxy;
import sampleApplication.view.HelloPanelMediator;

public class StartupCommand extends SimpleCommand implements ICommand
{

override public function execute(notification:INotification):void
{
facade.registerProxy(new HelloProxy());
var app:SampleProject = notification.getBody() as SampleProject;
facade.registerMediator(new HelloPanelMediator(app.hello));

}

}
}
MakeHelloCommand.as
:
package sampleApplication.controller
{
import org.puremvc.as3.interfaces.ICommand;
import org.puremvc.as3.interfaces.INotification;
import org.puremvc.as3.patterns.command.SimpleCommand;

public class MakeHelloCommand extends SimpleCommand implements ICommand
{
public static const NAME:String = "MakeHello";
public static const CMD_MAKE_HELLO:String = "MakeHello.MakeHello";

public function MakeHelloCommand()
{
super();
}

override public function execute(notification:INotification):void
{
}

}
}
HelloProxy.as
:
package sampleApplication.model
{
import org.puremvc.as3.interfaces.IProxy;
import org.puremvc.as3.patterns.proxy.Proxy;

public class HelloProxy extends Proxy implements IProxy
{
public static const NAME:String = "HelloProxy";

public function HelloProxy(data:Object = null)
{
super(NAME, data);
}

}
}
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #3 on: April 19, 2009, 12:31:11 »

Ok, the skeleton for some stuff is here.

But your HelloPanelMediator is trying to send a notification whose name doesn't exist. Instead of:
:
private function onOkClick(evt:Event):void
{
sendNotification(MakeHelloCommand.CMD_MAKE_HELLO, helloPanel.txName.text);
}

you're probably wanting to send:

:
private function onOkClick(evt:Event):void
{
sendNotification(ApplicationFacade.HELLO_OK_CLICKED, helloPanel.txName.text);
}

And you haven't registered anything to listen for that notification. I assume you want to register the MakeHelloCommand. So in your ApplicationFacade add the registration, and fix your package:


:

package sampleApplication.view
{
...
        import sampleApplication.controller.MakeHelloCommand;
...
                override protected function initializeController():void
{
registerCommand(STARTUP, StartupCommand);
registerCommand(HELLO_OK_CLICKED, MakeHelloCommand);
}
...

That should get the thread of execution into your MakeHelloCommand, but it's not doing anything. And it doesn't need to register a name or have a constructor, only execute. Try this:

:
import mx.controls.Alert;
public class MakeHelloCommand extends SimpleCommand implements ICommand
{


override public function execute(notification:INotification):void
{
      mx.controls.Alert.show("Hello", "Hi there");
}

}


So, here's a Super Simple demo that might be a better place for you to start. Thanks to Simon Bailey for this one:

http://www.nutrixinteractive.com/blog/?p=352

-=Cliff>
Logged
vladakg85
Full Member
***
Posts: 22


View Profile Email
« Reply #4 on: April 28, 2009, 02:59:54 »

Hi, me again ;)

I want to try to make application without proxy for now, because I don't understand proxy at the moment. My questions are:
Is it ok, to put GUI (like Alert) in commands? I think it's not, but what is another way?
Before I start to make proxy, and put Alert in it, I want to learn where to put ir becouse this is for sure wrong way :)

Does proxy return data to command later and command back to mediator > GUI, or proxy send data directly to mediator > GUI?

I wan't to start later to learn about how to switch view states, and is there any simple step-by-step tutorial to learn how to switch states in pureMVC (login state to register or login to mainApplicationState)?

Oh yea, is it ok to put all constatns of everything that should happened on GUI in to ApplicationFacade?
Like: loginClick, removeContact, removeUser, addContact, ....
==============================================
ApplicationFacade
:
package
{
import controller.HelloButtonClickCommand;
import controller.LoginHardcoddedCommand;
import controller.SquareNumberCommand;
import controller.StartupCommand;

import org.puremvc.as3.interfaces.IFacade;
import org.puremvc.as3.patterns.facade.Facade;
/**
* Facade klasa se uvek pravi, ona omogucava mediatorima, proxijima i komandama
* da komuniciraju.
* U njoj se nalaze konstante svih notifikacija.
* Singleton metod (getInstance)
* Registracija svih komandi (?)
* startup metod koji startuje aplikaciju i poziva se sa main.mxml fajla
* @author vvucetic
*
*/
public class ApplicationFacade extends Facade implements IFacade
{
// list od all notifications
public static const STARTUP:String = "startup";
public static const HELLO_BUTTON_CLICKED:String = "helloButtonClicked";
public static const SQUARE_BUTTON_CLICKED:String = "squareButtonClicked";
public static const LOGIN_HARDCODE:String = "loginHardcode";

public static function getInstance():ApplicationFacade
{
if (instance == null)
{
instance = new ApplicationFacade();
}
return instance as ApplicationFacade;
}

public function startup(app:Object):void
{
sendNotification(STARTUP, app);
}

override protected function initializeController():void
{
super.initializeController();

// registers commands
registerCommand(STARTUP, StartupCommand);
registerCommand(HELLO_BUTTON_CLICKED, HelloButtonClickCommand);
registerCommand(SQUARE_BUTTON_CLICKED, SquareNumberCommand);
registerCommand(LOGIN_HARDCODE, LoginHardcoddedCommand);
}

}
}
StartupCommand
:
package controller
{
import org.puremvc.as3.interfaces.ICommand;
import org.puremvc.as3.interfaces.INotification;
import org.puremvc.as3.patterns.command.SimpleCommand;

import view.HelloWindowComponentMediator;
/**
* Uvek postoji
* Registruje mediatore
* @author vvucetic
*
*/
public class StartupCommand extends SimpleCommand implements ICommand
{
override public function execute(notification:INotification):void
{
var app:HelloVlada = notification.getBody() as HelloVlada;

facade.registerMediator(new HelloWindowComponentMediator(app.HelloPanel));
}

}
}
HelloButtonClickCommand
:
package controller
{
import mx.controls.Alert;

import org.puremvc.as3.interfaces.ICommand;
import org.puremvc.as3.interfaces.INotification;
import org.puremvc.as3.patterns.command.SimpleCommand;

public class HelloButtonClickCommand extends SimpleCommand implements ICommand
{

override public function execute(notification:INotification):void
{
Alert.show("hello, " + notification.getBody() as String);
}

}
}
LoginHardcodedCommand
:
package controller
{
import model.vo.Login;

import mx.controls.Alert;

import org.puremvc.as3.interfaces.ICommand;
import org.puremvc.as3.interfaces.INotification;
import org.puremvc.as3.patterns.command.SimpleCommand;

public class LoginHardcoddedCommand extends SimpleCommand implements ICommand
{
override public function execute(notification:INotification):void
{
var userData:Login;

userData = notification.getBody() as Login;

if (userData.username == "vlada" && userData.password == "vlada")
{
Alert.show("welcome vlada");
}
else
{
Alert.show("wrong password");
}
}
}
}
HelloWindowComponent
:
<?xml version="1.0" encoding="utf-8"?>
<mx:Panel xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="400" height="400" title="test">
<!-- Simple component to test pureMVC framework-->
<mx:TextInput id="txName" text="vlada" x="10" y="10" width="160"/>
<mx:Button id="btnHello" label="hello" x="178" y="10" width="192" height="22"/>
<mx:TextInput id="txNumberToSquare" x="10" y="40" width="76"/>
<mx:Button id="btnSquare" x="178" y="40" label="square" width="192"/>
<mx:Button id="btnLogin" x="153" y="166" label="login"/>
<mx:TextInput id="txUsername" x="80" y="110" width="126"/>
<mx:TextInput id="txPassword" x="80" y="136" width="126"/>
<mx:Label x="10" y="112" text="Username"/>
<mx:Label x="10" y="138" text="Password"/>
</mx:Panel>

HelloWindowComponentMediator
:
package view
{
import flash.events.Event;
import flash.events.MouseEvent;

import model.vo.Login;

import org.puremvc.as3.interfaces.IMediator;
import org.puremvc.as3.interfaces.INotification;
import org.puremvc.as3.patterns.mediator.Mediator;

import view.components.HelloWindowComponent;
/**
* Mediator postoji za svaku komponentu i jedini osluskuje sta se desava
* na komponenti i na osnovu toga obavestava ostatak sistema.
* onRegister - registruju se svi dogadjaji
* listNotificationInterests - sve notifikacije koje ovaj mediator zanimaju
* handleNotification - handler za gore navedene notifikacije
* @author vvucetic
*
*/
public class HelloWindowComponentMediator extends Mediator implements IMediator
{
public static const NAME:String = "HelloWindowComponentMediator";

public function HelloWindowComponentMediator(viewComponent:Object=null)
{
super(NAME, viewComponent);
}

private function get helloWindowComponent():HelloWindowComponent
{
return viewComponent as HelloWindowComponent;
}

override public function onRegister():void
{
helloWindowComponent.btnHello.addEventListener(MouseEvent.CLICK, onHelloButtonClick);
helloWindowComponent.btnSquare.addEventListener(MouseEvent.CLICK, onSquareButtonClick);
helloWindowComponent.btnLogin.addEventListener(MouseEvent.CLICK, onLoginButtonClick);
}

private function onLoginButtonClick(evt:Event):void
{
var userLoginData:Login = new Login();
userLoginData.username = helloWindowComponent.txUsername.text;
userLoginData.password = helloWindowComponent.txPassword.text;

sendNotification(ApplicationFacade.LOGIN_HARDCODE, userLoginData);
}

private function onHelloButtonClick(evt:Event):void
{
sendNotification(ApplicationFacade.HELLO_BUTTON_CLICKED, helloWindowComponent.txName.text);
}

private function onSquareButtonClick(evt:Event):void
{
sendNotification(ApplicationFacade.SQUARE_BUTTON_CLICKED, helloWindowComponent.txNumberToSquare.text);
}

override public function listNotificationInterests():Array
{
return [ApplicationFacade.HELLO_BUTTON_CLICKED,
ApplicationFacade.SQUARE_BUTTON_CLICKED,
ApplicationFacade.LOGIN_HARDCODE];
}

override public function handleNotification(notification:INotification):void
{
switch (notification.getName())
{
case ApplicationFacade.HELLO_BUTTON_CLICKED:

break;
case ApplicationFacade.SQUARE_BUTTON_CLICKED:

break;
case ApplicationFacade.LOGIN_HARDCODE:

break;
}
}
}
}
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #5 on: April 28, 2009, 09:25:06 »

Looks like you're on your way here. This is all just fine. Alert boxes from commands are OK. When you need a more sophisticated dialog to gather info from the user, you may want to make it a component that gets its own mediator (for its short lifetime).

Here's some good info on popup handing from Simon Bailey:
http://www.nutrixinteractive.com/blog/?p=329

-=Cliff>
Logged
vladakg85
Full Member
***
Posts: 22


View Profile Email
« Reply #6 on: April 29, 2009, 01:04:59 »

Looks like you're on your way here. This is all just fine. Alert boxes from commands are OK. When you need a more sophisticated dialog to gather info from the user, you may want to make it a component that gets its own mediator (for its short lifetime).

Here's some good info on popup handing from Simon Bailey:
http://www.nutrixinteractive.com/blog/?p=329

-=Cliff>
Thank god :)
Until now I work only in .NET and I user 3 tier architecture. DAL acces database ... return data to BL ... BL return to the GUI, as I understand in pureMVC commands are BL (business logic), so it is OK to put GUI (Alert) in command?

Now I don't understand where is proxy here? What code go there and what and when it return some result? Should I use sendNotification( to send for example name) to the proxy and it connects that name in some string with "Hello, " and then return (or send notification) to command or mediador?
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #7 on: April 30, 2009, 04:38:17 »

Proxies hold data and broadcast notifications when it is loaded or changed. They don't listen for notifications, but are instead retrieved and manipulated by commands and/or mediators. For them to listen to notifications would be to tie them to tightly to the application implementation in the view/controller tiers, and hamper their reusability.

-=Cliff>
Logged
vladakg85
Full Member
***
Posts: 22


View Profile Email
« Reply #8 on: May 18, 2009, 05:12:57 »

Ok, and if I have scenario like this:
I have one database, I have one .NET service (ASP FluorineFX) that holds remote objects to connect to this database, and I have two classes that holds all methods, for example Users.cs for all user actions, and Tasks.cs for all tasks actions.
Now I have methods (on service): login, register, retrivePassword, sendEmail, addNewTask, getAllTasks, FindUserByName etc. Do I need, in Flex: loginProxy, retrivePasswordProxy, sendEmailProxy ... classes or I can have one proxy class to access all this methods on service?
I hope that someone understand what bother me :)
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #9 on: May 18, 2009, 05:44:49 »

You can put them all on a single proxy. This will also let you reuse a single fautl handler for all your calls.

-=Cliff>
Logged
vladakg85
Full Member
***
Posts: 22


View Profile Email
« Reply #10 on: June 08, 2009, 11:11:23 »

So if I have remote service and I wan't to retrive sam data, I connect to that remote server with Controller (like LoginCommand) return some data and store them in proxy, is that right?

Because as I understand, user type login data > mediator register OK click and invoke > LoginCommand, LoginCommand connect to server check for user existence and return data to that command > from command I store data in LoginProxy so that I can use this data later anywhere from application, right? ???
« Last Edit: June 08, 2009, 11:14:10 by vladakg85 » Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #11 on: June 09, 2009, 05:29:26 »

You really don't want to use commands to communicate with services. Long-lived actors are better for this, particularly if the service is called more than once. Use a Proxy to connect to the service. Sure you can have a Command invoke the Proxy method that calls the service.

-=Cliff>
Logged
Pages: [1]
Print