Initializing GraniteDS Tide framework - actionscript-3

I'm trying to work with GDS Tide framework. My basic code is this one :
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
preinitialize="Tide.getInstance().initApplication()">
<fx:Script>
<![CDATA[
import controllers.TestController;
import events.TestEvent;
import models.TestModel;
import models.interfaces.ITestModel;
import mx.events.FlexEvent;
import org.granite.tide.Tide;
[Bindable][Inject]
public var testModel:ITestModel;
Tide.getInstance().addComponents([TestController, TestModel]);
]]>
</fx:Script>
<s:layout>
<s:VerticalLayout />
</s:layout>
<s:Label text="{testModel.ab}" />
<s:Button click="dispatchEvent(new TestEvent());" label="test !" />
I can compile and run my code but when I'm launching my application, I see blank windows, my button or my label don't appear. No errors are fired.
When I change my code to this one :
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
preinitialize="Tide.getInstance().initApplication()" creationComplete="application1_creationCompleteHandler(event)">
<fx:Script>
<![CDATA[
import controllers.TestController;
import events.TestEvent;
import models.TestModel;
import models.interfaces.ITestModel;
import mx.events.FlexEvent;
import org.granite.tide.Tide;
[Bindable][Inject]
public var testModel:ITestModel;
protected function application1_creationCompleteHandler(event:FlexEvent):void
{
Tide.getInstance().addComponents([TestController, TestModel]);
}
]]>
</fx:Script>
<s:layout>
<s:VerticalLayout />
</s:layout>
<s:Label text="{testModel.ab}" />
<s:Button click="dispatchEvent(new TestEvent());" label="test !" />
it works I see label and button but my label isn't initialized properly because my controller and model are added on mx.events.FlexEvent.CREATION_COMPLETE event.
What am I doing wrong please with the first (and recommanded) method ?

Related

In flex 4.5 parentDocument did not working as in flex 4.0. How to call parentDocument in flex 4.5?

In flex 4.0 this code works:
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" width="500" height="600">
<fx:Script>
<![CDATA[
import componentCanvas;
import mx.containers.TitleWindow;
import mx.controls.Alert;
public function createChild():void{
var c:componentCanvas = new componentCanvas;
c.x = 20;
c.y=20;
toInclude.addChild(c);
}
]]>
</fx:Script>
<mx:Button click="createChild()"/>
<mx:Canvas id="toInclude"/>
--componentCanvas --
<mx:Canvas xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" width="400" height="300">
<fx:Script>
<![CDATA[
import componentCanvas;
import mx.containers.TitleWindow;
import mx.controls.Alert;
import mx.managers.PopUpManager;
import popAll;
public function oh():void{
Alert.show("From titleWindow");
}
public function open():void{
var pop:popAll = popAll(PopUpManager.createPopUp(this, popAll, true));
}
]]>
</fx:Script>
<mx:Label text="Canvas" x="100" y="100"/>
<mx:Button click="open()"/>
-- popAll --
<s:TitleWindow xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" width="400" height="300" x="40" y="40" close="closePopUp()">
<fx:Script>
<![CDATA[
import mx.managers.PopUpManager;
public function closePopUp():void{
super.parentDocument.oh();
PopUpManager.removePopUp(this);
}
]]>
</fx:Script>
<mx:Button click="closePopUp()"/>
When I call parentDocument in titleWindow in flex 4 all is fine.
The same code in 4.5 did not work.
Is there a way to do this in Flex 4.5?
Calling parentDocument and using public functions across all the files is definitely not the best practice! Instead, you should really look into the Event Life Cycle in Flex and how to use it. In my opinion, public methods should really be created when you want to expose a particular functionality of your component to it's users.
Basically, you should dispatch an event from the popAll class and listen to it within it's instance created in componentCanvas. So, to solve this issue, your code should be :
popAll:
<s:TitleWindow xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" width="400" height="300" x="40" y="40" close="closePopUp()">
<fx:Script>
<![CDATA[
import mx.managers.PopUpManager;
public function closePopUp():void{
this.dispatchEvent(new Event("closePopup"));
PopUpManager.removePopUp(this);
}
]]>
</fx:Script>
<mx:Button click="closePopUp()"/>
</s:TitleWindow>
and componentCanvas:
<mx:Canvas xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" width="400" height="300">
<fx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.managers.PopUpManager;
private var pop:popAll;
public function oh():void{
Alert.show("From titleWindow");
}
public function open():void{
pop = popAll(PopUpManager.createPopUp(this, popAll, true));
pop.addEventListener("closePopup", onClosePopupRequested);
}
protected function onClosePopupRequested(event:Event):void
{
pop.removeEventListener("closePopup", onClosePopupRequested);
oh();
}
]]>
</fx:Script>
<mx:Label text="Canvas" x="100" y="100"/>
<mx:Button click="open()"/>
</mx:Canvas>
As per the code above, I am dispatching a new Event called as closePopup from the popAll class and listening to it where I am creating it's instance. And then once the event is caught, I am removing the event handler and then calling your oh() method from within the event handler.
I would make a few more recommendations on your code:
Re-consider your naming convention of classes and methods, and please look into camel case naming convention
Avoid using too many public methods, instead use events to communicate between files/components. This would enable you to create loosely coupled components.
If you are moving to Flex 4.5, I would recommend you to use spark components instead of mx components. In my experience, they do have more versatility.
Look into creating constants for literals.
Hope this helps. Cheers.

How to access a public function outside custom component in flex?

I have an application width a mx:ViewStack component with differents view components under each s:NavigatorContent as it follows.
<mx:ViewStack id="vsOne" resizeToContent="true">
<s:NavigatorContent label="First">
<package:MyFirstComponent id="myFirstComponent"/>
</s:NavigatorContent>
<s:NavigatorContent label="Second">
<package:MySecondComponent id="mySecondComponent"/>
</s:NavigatorContent>
</mx:ViewStack>
And this is package.MyFirstComponent's important part..
<s:Button label="Next" click="somethingToGoForward()"/>
What I've tried:
Calling somethingToGoForward() in the view component and triyng to access to a parent vsOne: Don't work.
Calling parent.somethingToGoForward() (when this method is in the same mxml as the ViewStack): Don't work
How can I change my ViewStack's selectedIndex from anywhere outside the mxml file containing it?
Thanks.
This is an example using simple events:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" initialize="application1_initializeHandler(event)"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" xmlns:local="*">
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
protected function application1_initializeHandler(event:FlexEvent):void
{
viewStack.selectedChild=one;
}
protected function one_changeViewHandler(event:FlexEvent):void
{
viewStack.selectedChild=two;
}
protected function two_changeViewHandler(event:FlexEvent):void
{
viewStack.selectedChild=one;
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<mx:ViewStack id="viewStack" >
<local:ccomp id="one" changeView="one_changeViewHandler(event)" text="LAbel ONE">
</local:ccomp>
<local:ccomp id="two" changeView="two_changeViewHandler(event)" text="LAbel TWO" >
</local:ccomp>
</mx:ViewStack>
</s:Application>
ccomp is a custom component
<?xml version="1.0" encoding="utf-8"?>
<mx:HBox xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" width="400" height="300">
<fx:Metadata>
[Event(name="changeView", type="mx.events.FlexEvent")]
</fx:Metadata>
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
private var _text:String;
public function get text():String
{
return _text;
}
[Bindable]
public function set text(value:String):void
{
_text = value;
}
protected function button1_clickHandler(event:MouseEvent):void
{
this.dispatchEvent(new FlexEvent("changeView",true));
}
]]>
</fx:Script>
<fx:Declarations>
</fx:Declarations>
<s:Button label="Change" click="button1_clickHandler(event)">
</s:Button>
<s:Label fontSize="24" text="{text}">
</s:Label>
</mx:HBox>
Davide

How to JSON serialize an fx:Model

I'm testing out using fx:Models, serializing it to JSON is not working as expected however. In the example below I do not get the model's data in the JSON, all I get is the uuid. How can I serialize models to JSON cleanly?
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" creationComplete="application1_creationCompleteHandler(event)">
<fx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.events.FlexEvent;
protected function application1_creationCompleteHandler(event:FlexEvent):void
{
mod1.part = "Initial value";
}
]]>
</fx:Script>
<fx:Declarations>
<fx:Model id="mod1">
<data>
<part>{ti.text}</part>
</data>
</fx:Model>
</fx:Declarations>
<s:TextInput id="ti" x="98" y="155" text="{mod1.part}">
</s:TextInput>
<s:Button x="120" y="193" label="Read from model" click="Alert.show(mod1.part, 'Model Data')"/>
<s:Button x="120" y="220" label="Model as JSON" click="Alert.show(JSON.stringify(mod1), 'Model as JSON')"/>
I was able to serialize the data as JSON by changing your stringify call to...
JSON.stringify(mod1.valueOf())

pass variable from a component to TitleWindow in Flex4

I am trying to access a variable defined in an mxml component from a TitleWindow but I cannot get it. I also declared a variable in my titleWindow which references to the component. And I also tried using parentDocument to access the variable but in vain.
Any precious help on this. Thanks.
See my codes below:
This is my component (Comp.xml) where I have declared the variable testVar.
<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
width="100%" height="100%">
<fx:Script>
<![CDATA[
public var testVar:String = "Testing";
]]>
</fx:Script>
</s:Group>
This is my titleWindow code:
<?xml version="1.0" encoding="utf-8"?>
<s:TitleWindow xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" left="10"
creationComplete="titlewindow1_initializeHandler(event)"
width="100%" height="100%"
>
<fx:Script>
<![CDATA[
import mx.controls.Alert;
import com.Comp;
public var varComp:Comp;
public function titlewindow1_initializeHandler(event:FlexEvent):void
{
//Alert.show(new String(Application));
Alert.show(new String(varComp.testVar));
}
]]>
</fx:Script>
</s:TitleWindow>

Manipulate data object in a itemrenderer - Adobe Flex 4

I have a simple Itemrenderer with the following code:
<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
autoDrawBackground="true" width="90" height="90">
<s:VGroup horizontalAlign="center">
<mx:Image source="{data.photo}" toolTip="{data.name}" />
</s:VGroup>
</s:ItemRenderer>
I would like to manipulate the data object before that it's binded to the image attributes (source and tooltip). To do this, I modified the code in this way:
<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
autoDrawBackground="true" width="90" height="90"
initialize="itemrenderer1_initializeHandler(event)">
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
protected function itemrenderer1_initializeHandler(event:FlexEvent):void
{
var obj:Object = this.data;
//here the manipulation
}
]]>
</fx:Script>
<s:VGroup horizontalAlign="center">
<mx:Image source="{data.photo}" toolTip="{data.name}" />
</s:VGroup>
</s:ItemRenderer>
When I try to access to the this.data object, it's always empty! Is there a way to manipulate the data object before binding? Probably i don't have to use this.data, but i cannot find any other object to edit
Another solution would be to override the set data function, like this:
<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
autoDrawBackground="true" width="90" height="90"
creationComplete="itemrenderer1_creationCompleteHandler(event)"
>
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
import valueObjects.Product;
[Bindable]
private var prd:Product;
override public function set data(value:Object):void
{
super.data = value;
//here i can access to the this.data object!
this.prd = this.data as Product;
}
]]>
</fx:Script>
<s:VGroup horizontalAlign="center">
<mx:Image source="{prd.photo}" toolTip="{prd.name}" width="70" />
<mx:Label text="{prd.name}"/>
</s:VGroup>
I found it! I can access to the this.data object only when the creation of the ItemRenderer is completed! to this I have to manipulate the object after the creationComplete event!
Here the code:
<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
autoDrawBackground="true" width="90" height="90"
creationComplete="itemrenderer1_creationCompleteHandler(event)"
>
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
import valueObjects.Product;
[Bindable]
private var prd:Product;
protected function itemrenderer1_creationCompleteHandler(event:FlexEvent):void
{
//here i can access to the this.data object!
this.prd = this.data as Product;
}
]]>
</fx:Script>
<s:VGroup horizontalAlign="center">
<mx:Image source="{prd.photo}" toolTip="{prd.name}" width="70" />
<mx:Label text="{prd.name}"/>
</s:VGroup>
</s:ItemRenderer>
Although not a new thread, do NOT go with CreationComplete. The event is invoked only once. The data will be set whenever the hosting component decides that the itemRenderer should be re-used. E.g. useVirtualLayout=true for a list.