Signal is never being injected - robotlegs2.0 - actionscript-3

In app config file I have a Signal/Command mapping
signalCommandMap.map(DisconnectUserSignal).toCommand(DisconnectUserCommand);
Then,
I have two connection classes:
public class BaseConnection implements IBaseConnection
{
// When I am trying to inject the signal here:
[Inject] public var disconnectUserSignal:DisconnectUserSignal; // it is always null
_netConnection = new NetConnection();
...
}
and
public class BBConnection extends DefaultConnectionCallback implements IBBConnection
{
// When I am trying to inject the signal here:
[Inject] public var disconnectUserSignal:DisconnectUserSignal; // it works perfectly fine
_baseConnection = new BaseConnection(this);
}
Is there any suggestion of what might be the reason?
Thank you

After going through the robotlegs framework documentation - I found the answer:
I changed the _baseConnection to be an interface, and moved everything from BaseConnection's constructor into init method and now I am injecting it inside my BBConnection.
Here how BBConnection looks now:
[Inject]
public var baseConnection:IBaseConnection;
public function BBConnection()
{
}
[PostConstruct]
public function init():void
{
baseConnection.init(this);
}
Now I can successfully inject Disconnect signal inside base connection.
Source: https://github.com/robotlegs/robotlegs-framework/wiki/common-problems#injected-properties-are-null-in-constructor

Related

Flex actionscript, get data from AsyncToken call

I have Flex/Java project with blazeDS. Now I have an actionscript file that call a method of another actionscript that call the remoteObject (java class who make a simple select on db)
Here's the code:
Home.as
..
private var _dm:DataManager = new DataManager;
public function getPerson():void { // this is connect to a button in .mxml
_dm.getPerson();
}
..
DataManager.as
public class DataManager {
private var _service:RemoteObject;
private var _url:URLRequest;
private var loCs:ChannelSet = new ChannelSet();
public function DataManager () {
_service = new RemoteObject("PeopleDAO");
loCs.addChannel(new AMFChannel("canale", "http://localhost:8080/FlexTRYOUT/messagebroker/amf"));
_service.channelSet = loCs;
}
private function onFault(event:FaultEvent,token:Object):void {
var _fail:String = "fault";
}
private function onResult(event:ResultEvent,token:Object):void {
per = event.result as People; // is a bean class
Alert.show(per.nome);
}
public function getPerson():void {
var token:AsyncToken = _service.getPersona();
token.addResponder(new AsyncResponder(onResult,onFault));
}
}
The call works fine, it calls java method names getPerson() of the DataManger.java class. It return simply one object with name and surname (it's just a hello world to understand this damned AsyncCall). The problem is that I don't know how send this result to Home.as with a classic (java) return type. I have the result in onResult method and I don't know how to get it.
I try to follow Brian instructions and I just waste my time. Maybe because I'm not a flex actionscript programmer but I added the code Brian posted and:
public function getPerson():void { // this is connect to a button in .mxml
_dm.addEventListener(DATA_RECEIVED, onPersonFound); * compile error 1
_dm.getPerson();
}
error is DATA_RECEIVED is undefined
than in DataManager:
public class DataManager {
public static const DATA_RECEIVED:String = "DATA_RECEIVED";
...
private function onResult(event:ResultEvent,token:Object):void {
per = event.result as People; // is a bean class
dispatchEvent(new DataReceivedEvent(DATA_RECEIVED, per)); * compile error 2
}
}
error 2 is call of possible undefined method dispatchEvent
Where is the mistake? Please guys write the complete code because I'm on flex - actionscript - blazeds from two days and I have a few time to try solution. Thanks
OK, Sorry for all this post, I just create new one (but more elaborated and clear) with the same question. Step by Step I'm studing this language and I manage to implement the Brian code but DataManager.as class must extend EventDispatcher, if I don't extend this I have the compile error I posted. At moment I mangage to obtain the resultEvent data in the method defined in the addEventListener call (onPeopleFound in this case). Thanks a lot Brian I think I surely need your help again in future (at least until acceptance of the project). Bye
You can adjust method getPerson to have two parameters referencing the callback functions.
public function getPerson(onResultCallback:Function, onFaultCallback:Function):void {
var token:AsyncToken = _service.getPersona();
token.addResponder(new AsyncResponder(onResultCallback,onFaultCallback));
}
This way you can receive data in an instance of the class you need.
One option is to dispatch an event when you get the data back from the Java call:
Home.as
...
public function getPerson():void { // this is connect to a button in .mxml
_dm.addEventListener(DATA_RECEIVED, onPersonFound);
_dm.getPerson();
}
private function onPersonFound(dataEvent:DataReceivedEvent):void {
var person:People = dataEvent.people;
//Do important processing...
}
...
In DataManager.as
public class DataManager {
public static const DATA_RECEIVED:String = "DATA_RECEIVED";
...
private function onResult(event:ResultEvent,token:Object):void {
per = event.result as People; // is a bean class
dispatchEvent(new DataReceivedEvent(DATA_RECEIVED, per));
}
}
And DataReceivedEvent.as will look like the answer to How to dispatch an event with added data - AS3
public class DataReceivedEvent extends Event
{
public static const DATA_RECEIVED:String = "DATA_RECEIVED";
// this is the object you want to pass through your event.
public var result:Object;
public function DataReceivedEvent(type:String, result:Object, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
this.result = result;
}
// always create a clone() method for events in case you want to redispatch them.
public override function clone():Event
{
return new DataReceivedEvent(type, result, bubbles, cancelable);
}
}

How to Make Popup window as Global in Flex?

Actually in my Flex Application have Some Popup windows and i want take some values in this Popup Window But The Values are Comming NULL
So how to Make a PopUp Window as Global? Because we are Using the values Globally.
Please Give Suggestion...
Edit
I'm Edit with some code...
Main.mxml(Main Aplication), Demo1.mxml(PopUpWindow), Demo2.mxml(PopUpWindow)
Now in Demo1.mxml have variable like...
[Bindable]private var arrayC:ArrayCollection=new ArrayCollection();//Hear Some value their.
NOw i want Use arrayC in Demo2.mxml then ..
public var variable1:Demo1=new Demo1();
var ac:ArrayCollection = new ArrayCollection();
ac = variable1.arrayC;
But hear ac contain Null Value Why?
Then,Now i'm Thinking Demo2.mxml(PopUpWindow) is Converting To Global Scope so it's value Used in Any Where .
Null because of you are tried create new instance so that each instance having their own state.
Also i bet you can't access arrayC ArrayCollection variable declared as private so you can't acccess.
Need to follow few steps
[Bindable]public var arrayC:ArrayCollection=new ArrayCollection(); //Make public variable
Use Singleton Class for you application
package com.foo.bar {
public class Model {
private static var instance : Model;
public function Model( enforcer : SingletonEnforcer ) {}
public static function getInstance() : Model {
if (!instance) {
instance = new Model( new SingletonEnforcer() );
}
return instance;
}
public var arrayC:ArrayCollection = new ArrayCollection();
}
}
class SingletonEnforcer{}
For more details Singleton pattern
private var popup:Demo1;
popup = PopUpManager.createPopUp(this,Demo1,true) as Demo1;
popup.arrayC = Model.getInstance().arrayC; // Here set value from Model class
PopUpManager.centerPopUp(popup);
Suppose you tried to access demo1.mxml arrayC variable in Demo2.mxml
var demo1_arrayC = Model.getInstance().arrayC;
Note that you can access arrayC arraycollection anywhere in your application like Demo2.mxml,Demo3...etc.
But better we have to avoid Singleton Class (unit test diffcult ..etc).
If you are using the values Globally, then no matter what you mean by the "Make a PopUp Window as Global", I strongly suspect that you would be best served by a singleton event dispatcher.
package com.example.demo.models {
import flash.events.IEventDispatcher;
import flash.events.EventDispatcher;
[Bindable]
class MyGlobalStuff extends EventDispatcher {
public var someGlobalValue:*;
private var _instance:MyGlobalStuff;
public function MyGlobalStuff (lock:SingletonLock, target:IEventDispatcher=null) {
super(target);
if(!(lock is SingletonLock)) {
throw(new Error("MyGlobalStuff is a singleton, please do not make foreign instances of it"));
}
}
public static function getInstance():MyGlobalStuff {
if(!_instance) {
_instance = new MyGlobalStuff (new SingletonLock());
}
return _instance;
}
}
}
class SingletonLock{}
The idea is this: that you would bind in your popup to
{myStuffModel.someGlobalValue}
myStuffModel would be initialized in your mxml as:
protected var myStuffModel:MyStuffModel = MyStuffModel.getInstance();
then in any other class throughout your application you can bind to or access the EXACT same data via the singleton model.

How to access a Class in the default package from a sub package Class in Flash AS3.0

I got error message when trying to access a class in the default package from the class in its sub package. Can any one help me to sort this out.
FYI, my package structure is A -> B. I meant folder 'A' as default package and 'B' as sub package.
Thanks in advance.
Just create a object of Class A, and call class instance method, from its object.
var classAObj:A = new A();
classObj.MethodA();
I think what you're looking for is for class B to extend class A. That would look something like this in your code:
package main
{
class B extends A
{
// Code here...
}
}
Having code inside packages does not in general affect functionality, it's more an organizational tool. (Except for the internal keyword.)
how about private, protected and public ? I could not see any explanation in the other answers so here it is.
class A
{
private var _password:String;
public var username:String;
protected var serverURL:String;
public function login():void
{
// some code
callServerForLogin();
}
protected function callServerForLogin():void
{
// some code
}
}
class B extends A
{
public function B()
{
var parentPassword = super._password;
// FAILS because private and accessible only inside class A
var parentUsername = super.username
// all ok in here, public property
var parentServerURL = super.serverURL;
// all ok, because it is protected
// also we can call super.login(); or super.callServerForLogin();
}
// IMPORTANT we are also allowed to override public and protected functions
override public function login():void
{
super.login();
// we call the parent function to prevent loosing functionality;
Alert.show("Login called from class B");
}
override protected function callServerForLogin():void
{
super.callServerForLogin();
// keep also parent logic
Alert.show("calling protected method from B");
}
}
// ---- Now considering you declare an object of type B you can do the following
var bObj:B = new B();
// access public properties and call public functions from both B and A
bObj.username = "superhero";
bObj.login();
// will get compile error for next lines
bObj.serverURL = "host.port";
bObj.callServerForLogin();

flash.utils.IExternalizable + Remoting + Flex Error #2004

There is a client - server basic application. The client uses a simple remoting to comunicate with the server side. The server side could be powered on WebORB, BlazeDS or any other product. The client side is using the FLEX framework. That is it about a technologies stack. Now, let's forget about the server side and just have a look on the following client side
package com.blog.ri
{
import mx.collections.ArrayCollection;
public class MyCollection extends ArrayCollection
{
public function MyCollection(source:Array=null)
{
super(source);
}
}
}
Additionally, let's assume we have the following class and it is mapped to the server side class:
package com.blog.ri
{
[Bindable]
[RemoteClass(alias="com.blog.ri.MyEntity")]
public dynamic class MyEntity
{
private var _myCollection:MyCollection;
public function get myCollection():MyCollection
{
if(_myCollection == null)
_myCollection = new MyCollection();
return _myCollection;
}
public function set myCollection(value:MyCollection):void
{
_myCollection = value;
}
}
}
Also, the server side service expose for clients the void save(MyEntity candidate) method and I implemented it on the client side as it shown below:
package com.blog.ri
{
public class MyService
{
private var _remoteObject:RemoteObject;
public function MyService()
{
var channelSet:ChannelSet = new ChannelSet();
var amfChannel:AMFChannel = new AMFChannel("my-amf", "http://localhost/weborb.aspx");
channelSet.addChannel(amfChannel);
_remoteObject = new RemoteObject("GenericDestination");
_remoteObject.channelSet = channelSet;
_remoteObject.source = "com.blog.ri.MyService";
_remoteObject.getDetailedStatistic.addEventListener("result",onItemSaved);
_remoteObject.addEventListener("fault", onFault);
}
public function save(candidate:MyEntity, responder:IResponder = null ):void
{
var asyncToken:AsyncToken = _remoteObject.save(candidate);
if( responder != null )
asyncToken.addResponder( responder );
}
}
}
Finally, I tried to save a new instance of the MyEntity class in our main mxml file as it shown below:
protected function creationCompleteHandler():void
{
var myService:MyService = new MyService();
var candidate:MyEntity = new MyEntity();
candidate.myCollection = new MyCollection();
myService.save(candidate);
}
That is it. When I run the code, I received the following exception:
ArgumentError: Error #2004: One of the parameters is invalid. at
flash.net::NetConnection/invokeWithArgsArray() at
flash.net::NetConnection/call() at
mx.messaging.channels::NetConnectionChannel/internalSend()[E:\dev\hero_private\frameworks\projects\rpc\src\mx\messaging\channels\NetConnectionChannel.as:281]
at
mx.messaging.channels::AMFChannel/internalSend()[E:\dev\hero_private\frameworks\projects\rpc\src\mx\messaging\channels\AMFChannel.as:364]
at
mx.messaging::Channel/send()[E:\dev\hero_private\frameworks\projects\rpc\src\mx\messaging\Channel.as:1002]
at
mx.messaging.channels::PollingChannel/send()[E:\dev\hero_private\frameworks\projects\rpc\src\mx\messaging\channels\PollingChannel.as:394]
at
mx.messaging::ChannelSet/send()[E:\dev\hero_private\frameworks\projects\rpc\src\mx\messaging\ChannelSet.as:1429]
at
mx.messaging::ChannelSet/channelConnectHandler()[E:\dev\hero_private\frameworks\projects\rpc\src\mx\messaging\ChannelSet.as:1084]
at flash.events::EventDispatcher/dispatchEventFunction() at
flash.events::EventDispatcher/dispatchEvent() at
mx.messaging::Channel/connectSuccess()[E:\dev\hero_private\frameworks\projects\rpc\src\mx\messaging\Channel.as:1148]
at
mx.messaging.channels::AMFChannel/resultHandler()[E:\dev\hero_private\frameworks\projects\rpc\src\mx\messaging\channels\AMFChannel.as:576]
As you can see, I extended the ArrayCollection class and according to the Adobe documentation, the ArrayCollection implements the IExternalizable interface. I decided to localize the problem and created a simple class that implements IExternalizable. Then, I extended this class in some other MyChild class and defined the MyChild property in the MyEntity class. In this case, I received the exception above as well. Is there a problem how I wrote the code or it is a bug within flex?
Thanks for any help.
The question is duplicated in my blog.
You could try:
registerClassAlias( "mx.collections.ArrayCollection", ArrayCollection);
registerClassAlias("flex.messaging.io.ArrayCollection", ArrayCollection);
Try adding an alias for MyCollection.
I got the unhelpful Error #2004 until all of my classes implementing IExternalizable had aliases. In my case it was for persistence (ViewNavigatorApplicationBase.persistNavigatorState = true) in which case I had to make sure I called registerClassAlias early enough in the startup to precede View.deserializeData(). The preinitialize event on the app works ok.
Some of your classes being (de)serialized is probably not linked into Flex project. Try adding following to your main Application/Module file:
private var forceReference:Array = [YourClass1, YourClass2];

Flex Strongly Typed Proxy Classes for Lazy Instantiation

Does anyone know of a framework, preferably some way to have the Flex compiler run an extension or perhaps just a build step that we could generate strongly typed proxy classes of our application's data models.
There are 2 main things we want to do with the proxy's:
At runtime we want to lazily parse and instantiate the instance as accessed (similiar to how Java's Hibernate has Lazy proxy objects)
In an editor application we want to implement setter calls so we can track which objects have been modified
The Proxy is really necessary in this situation beyond things like programatically setting up ChangeWatcther's because we need to track Array adds/remove and possibly track "reference" objects so that when a "reference key" is changed we know to save those objects that are referencing it by key
In the first case we want the proxy to basically abstract when that object is loaded from serialized data, but still pass around references of it with the same public properties and data access pattern if it were the real object.
Basically the proxy would instantiate the object the first time a method is called on it.
I know we could use some AS3 byte-code libraries like as3-commons-bytecode.
Or possibly repurposing the GraniteDS Code Generation.
I'd prefer to generate code because it is a deterministic thing and it'd be nice if we could have a way to debug it at runtime easier.
Does anyone know if I could do something like MXMLC does when it generates AS3 code from MXML files.
Also is there anyway to control "when" in the compilation pipeline I can generate code, because we have a lot of data objects using public fields instead of getter/setters, but that are [Bindable] and so if I could generate the proxy based on the generated getter/setter methods that would work.
Here's an example application data object and proxy classes:
[Bindable]
public class PersonDTO implements Serializable {
private var _name:String;
private var _age:Number
public function get age():Number {
return _age;
}
public function set age(a:Number):void {
_age = a;
}
public function get name():String {
return _name;
}
public function set name(n:String):void {
_name = n;
}
public void readObject(data:*) {
//...
}
}
// GENERATED CLASS BASED ON PersonDTO
public class LazyProxy_PersonDTO extends PersonDTO {
private var _instance:PersonDTO = null;
private var _instanceData:*;
private function getInstance():void {
if (_instance == null) {
_instance = new PersonDTO();
_instance.readObject(_instanceData);
}
}
override public function get age():Number {
//Ensure object is instantiated
return getInstance().age;
}
override public function get name():String {
//Ensure object is instantiated
return getInstance().name;
}
}
// GENERATED CLASS BASED ON PersonDTO
public class LogChangeProxy_PersonDTO extends PersonDTO {
//This will be set in the application
public var instance:PersonDTO;
//set by application
public var dirtyWatcher:DirtyWatcherManager;
override public function set age(a:Number):void {
dirtyWatcher.markAsDirty(instance);
instance.age = a;
}
}
Digging a little deeper into AS3-Commons byte code library it looks like they support generating proxy classes and interceptors.
http://www.as3commons.org/as3-commons-bytecode/proxy.html
public class DirtyUpdateInterceptor implements IInterceptor {
public function DirtyUpdateInterceptor() {
super();
}
public function intercept(invocation:IMethodInvocation):void {
if (invocation.kind === MethodInvocationKind.SETTER) {
if (invocation.arguments[0] != invocation.instance[invocation.targetMember]) {
invocation.instance.isDirty = true;
}
}
}
}