Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Stock quote and Login Example both use new approach with controllers …

…services and models
  • Loading branch information...
commit ed4284e008481fa9d547c31fe7f6d21d3128dd77 1 parent 6296b34
@seanhess authored
View
40 examples/GlueLoginExample/src/login/control/Authentication.mxml
@@ -1,45 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
-<mx:Object xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:model="login.model.*" xmlns:service="login.service.*">
+<mx:Object xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:model="login.model.*" xmlns:service="login.service.*" xmlns="http://glue.seanhess.net/2009">
+ <!--
+ This controller is responsible for invoking services and
+ manipulating models.
+ -->
+
+ <!-- Models: These are injected -->
<model:Application id="app"/>
<model:Navigation id="nav"/>
- <mx:HTTPService id="loginService" url="../server/login.php" resultFormat="object" result="onLogin(event)">
- <mx:request>
- <username>{currentAttempt.username}</username>
- <password>{currentAttempt.password}</password>
- </mx:request>
- </mx:HTTPService>
-
- <mx:HTTPService id="logoutService" url="../server/logout.php" resultFormat="object" result="onLogout(event)">
- </mx:HTTPService>
-
+ <!-- Services: Either injected or created. -->
<service:ParseAuthResponses id="parser"/>
+
+ <!-- These tags make it so we can listen to any service that is injected with minimal code -->
+ <Respond id="respondLogin" result="onLogin(event.source)"/>
+ <Respond id="respondLogout" result="onLogout(event.source)"/>
<mx:Script>
<![CDATA[
import mx.rpc.events.ResultEvent;
+ import mx.rpc.http.HTTPService;
import login.model.Login;
import login.model.User;
- [Bindable] public var currentAttempt:Login;
+ // These are injected in from the glue
+ [Bindable] public var loginService:HTTPService;
+ [Bindable] public var logoutService:HTTPService;
+
+ private var currentAttempt:Login;
public function login(value:Login):void
{
currentAttempt = value;
- currentAttempt.failed = false;
- currentAttempt.waiting = true;
- loginService.send();
+ currentAttempt.start();
+ respondLogin.start(loginService);
+ loginService.send({username:currentAttempt.username, password:currentAttempt.password});
}
public function logout():void
{
+ respondLogout.start(logoutService);
logoutService.send();
}
- /**
- * This is some logic, but it's testable by mocking the services
- */
private function onLogin(event:ResultEvent):void
{
currentAttempt.waiting = false;
View
10 examples/GlueLoginExample/src/login/glue/MainGlue.mxml
@@ -7,13 +7,21 @@
]]>
</mx:Script>
+ <!-- SERVICES :: These could be in another file -->
+ <mx:HTTPService id="login" url="../server/login.php" resultFormat="object"/>
+ <mx:HTTPService id="logout" url="../server/logout.php" resultFormat="object"/>
+
+ <service:MockLoginService id="mockLogin"/>
+ <service:DoNothingService id="doNothing"/>
+
+
<!-- MODELS -->
<model:Application id="app"/>
<model:Navigation id="nav"/>
<!-- CONTROLLERS -->
- <control:Authentication id="auth" app="{app}" nav="{nav}"/>
+ <control:Authentication id="auth" app="{app}" nav="{nav}" loginService="{mockLogin}" logoutService="{doNothing}"/>
<Glue>
<view:MainView id="mainView"/>
View
6 examples/GlueLoginExample/src/login/model/Login.as
@@ -20,5 +20,11 @@ package login.model
waiting = false;
failed = false;
}
+
+ public function start():void
+ {
+ waiting = true;
+ failed = false;
+ }
}
}
View
15 examples/GlueLoginExample/src/login/service/DoNothingService.as
@@ -0,0 +1,15 @@
+package login.service
+{
+ import mx.rpc.AsyncToken;
+ import mx.rpc.events.ResultEvent;
+ import mx.rpc.http.HTTPService;
+
+ public class DoNothingService extends HTTPService
+ {
+ override public function send(parameters:Object=null):AsyncToken
+ {
+ dispatchEvent(ResultEvent.createEvent(true));
+ return null;
+ }
+ }
+}
View
34 examples/GlueLoginExample/src/login/service/MockAuthenticationService.as
@@ -1,34 +0,0 @@
-package login.service
-{
- import flash.events.EventDispatcher;
-
- import login.model.event.LoginExample;
-
- [Bindable]
- public class MockAuthenticationService extends EventDispatcher implements IAuthenticationService
- {
- public var email:String;
- public var authenticated:Boolean;
-
- public function login(username:String, password:String):void
- {
- if (username == "bob" && password == "bob")
- {
- authenticated = true;
- email = "bob@bob.com";
- }
-
- else
- {
- authenticated = false;
- }
-
- dispatchEvent(new Event(LoginExample.LOGIN));
- }
-
- public function logout():void
- {
- dispatchEvent(new Event(LoginExample.LOGOUT));
- }
- }
-}
View
29 examples/GlueLoginExample/src/login/service/MockLoginService.as
@@ -0,0 +1,29 @@
+package login.service
+{
+ import mx.rpc.AsyncToken;
+ import mx.rpc.events.ResultEvent;
+ import mx.rpc.http.mxml.HTTPService;
+
+ /**
+ * can swap this out for the actual php services to get it to
+ * work without an internet connection.
+ *
+ * You should override the parsers too?
+ */
+ [Bindable]
+ public class MockLoginService extends HTTPService
+ {
+ public var result:Object = {
+ response: {
+ email: "henry@mydomain.com",
+ authenticated: true
+ }
+ }
+
+ override public function send(parameters:Object=null):AsyncToken
+ {
+ dispatchEvent(ResultEvent.createEvent(result));
+ return null;
+ }
+ }
+}
View
BIN  examples/StockQuote/libs/Glue0.2.a.swc
Binary file not shown
View
BIN  examples/StockQuote/libs/Glue0.3.a.swc
Binary file not shown
View
19 examples/StockQuote/src/stocks/control/Quotes.mxml
@@ -1,19 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
-<fx:Object xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/halo" xmlns:business="com.asfusion.mate.stockQuoteExample.business.*" xmlns:service="stocks.service.*">
+<fx:Object xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/halo" xmlns:business="com.asfusion.mate.stockQuoteExample.business.*" xmlns:service="stocks.service.*" xmlns:glue="http://glue.seanhess.net/2009">
<fx:Declarations>
- <mx:HTTPService id="quoteService"
- url="http://judstephenson.com/api/Quotes/Realtime/{quote.symbol}"
- resultFormat="object"
- result="onResult(event)"
- fault="onFault(event)"
- />
-
- <service:QuoteServiceParser id="parser"/>
+ <glue:Respond id="respondQuote" result="onResult(event.source)" fault="onFault(event)"/>
</fx:Declarations>
<fx:Script>
<![CDATA[
+ import stocks.service.IQuoteService;
+ import stocks.service.QuoteServiceParser;
import mx.rpc.AbstractOperation;
import mx.controls.Alert;
import mx.rpc.events.ResultEvent;
@@ -22,10 +17,14 @@
[Bindable]
private var quote:Quote;
+ public var quoteService:IQuoteService;
+ public var parser:QuoteServiceParser; // not an interface, but you could extend it to mock it
+
public function getQuote(quote:Quote):void
{
this.quote = quote;
- quoteService.send();
+ respondQuote.start(quoteService);
+ quoteService.getQuote(quote.symbol);
}
private function onResult(event:ResultEvent):void
View
6 examples/StockQuote/src/stocks/glue/MainGlue.mxml
@@ -2,8 +2,12 @@
<GlueMap xmlns="http://glue.seanhess.net/2009" xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/halo" xmlns:view="stocks.view.*" xmlns:control="stocks.control.*" xmlns:mate="http://mate.asfusion.com/" xmlns:service="stocks.service.*">
<fx:Declarations>
+ <!-- SERVICE -->
+ <service:QuoteService id="quoteService"/>
+ <service:RandomQuoteService id="randomQuoteService"/>
+
<!-- CONTROL -->
- <control:Quotes id="quotes"/>
+ <control:Quotes id="quotes" quoteService="{quoteService}"/>
<!-- VIEW -->
<Glue>
View
9 examples/StockQuote/src/stocks/service/IQuoteService.as
@@ -0,0 +1,9 @@
+package stocks.service
+{
+ import flash.events.IEventDispatcher;
+
+ public interface IQuoteService extends IEventDispatcher
+ {
+ function getQuote(symbol:String):void;
+ }
+}
View
15 examples/StockQuote/src/stocks/service/QuoteService.as
@@ -0,0 +1,15 @@
+package stocks.service
+{
+ import mx.rpc.http.HTTPService;
+
+ public class QuoteService extends HTTPService implements IQuoteService
+ {
+ private const URL:String = "http://judstephenson.com/api/Quotes/Realtime/";
+
+ public function getQuote(symbol:String):void
+ {
+ this.url = URL + symbol;
+ send();
+ }
+ }
+}
View
16 examples/StockQuote/src/stocks/service/RandomQuoteService.as
@@ -0,0 +1,16 @@
+package stocks.service
+{
+ import flash.events.EventDispatcher;
+
+ import mx.rpc.events.ResultEvent;
+
+ public class RandomQuoteService extends EventDispatcher implements IQuoteService
+ {
+ public function getQuote(symbol:String):void
+ {
+ var price:String = (Math.random() * 1000).toFixed(2);
+ var result:Object = {quote:{stock:{price:{current:price}}}}
+ dispatchEvent(ResultEvent.createEvent(result));
+ }
+ }
+}
View
2  source/src/manifest.xml
@@ -4,6 +4,8 @@
<component class="net.seanhess.glue.Glue"/>
<component class="net.seanhess.glue.IGlueAction"/>
<component class="net.seanhess.glue.Observe"/>
+ <component class="net.seanhess.glue.Respond"/>
+ <component class="net.seanhess.glue.RespondEvent"/>
<component class="net.seanhess.glue.Smart"/>
<component class="net.seanhess.glue.GlueMap"/>
<component class="net.seanhess.glue.Route"/>
View
49 source/src/net/seanhess/glue/Respond.as
@@ -0,0 +1,49 @@
+package net.seanhess.glue
+{
+ import flash.events.Event;
+ import flash.events.EventDispatcher;
+ import flash.events.IEventDispatcher;
+
+ import mx.rpc.events.FaultEvent;
+ import mx.rpc.events.ResultEvent;
+
+ /**
+ */
+ [Event(name="result",type="net.seanhess.glue.RespondEvent")]
+ [Event(name="fault", type="net.seanhess.glue.RespondEvent")]
+ public class Respond extends EventDispatcher
+ {
+ public var resultEvent:String = ResultEvent.RESULT;
+ public var faultEvent:String = FaultEvent.FAULT;
+ public var autoFinish:Boolean = true;
+
+ public var instance:IEventDispatcher;
+
+ public function start(instance:IEventDispatcher):void
+ {
+ this.instance = instance;
+ instance.addEventListener(resultEvent, onResult);
+ instance.addEventListener(faultEvent, onFault);
+ }
+
+ public function finish():void
+ {
+ instance.removeEventListener(resultEvent, onResult);
+ instance.removeEventListener(faultEvent, onFault);
+ }
+
+ private function onResult(event:Event):void
+ {
+ if (autoFinish) finish();
+ dispatchEvent(new RespondEvent(RespondEvent.RESULT, event));
+ }
+
+ private function onFault(event:Event):void
+ {
+ if (autoFinish) finish();
+ dispatchEvent(new RespondEvent(RespondEvent.FAULT, event));
+ }
+
+
+ }
+}
View
21 source/src/net/seanhess/glue/RespondEvent.as
@@ -0,0 +1,21 @@
+package net.seanhess.glue
+{
+ import flash.events.Event;
+
+ import mx.rpc.events.FaultEvent;
+ import mx.rpc.events.ResultEvent;
+
+ public class RespondEvent extends Event
+ {
+ public static const RESULT:String = ResultEvent.RESULT;
+ public static const FAULT:String = FaultEvent.FAULT;
+
+ public var source:*;
+
+ public function RespondEvent(type:String, source:*):void
+ {
+ this.source = source;
+ super(type);
+ }
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.