Flex: Passing MXML file as XML Parameter - apache-flex

Is it Possible to pass MXML it self as parameter(XML param) from external application and load in Flash Player dynamically to create page. For e.g
passing xml = <mx:canvas><mx:label text="hello" /></mx:canvas> to Flex and flex should create canvas with label control in it. Is there any example related to it.
Thanx

MXML code needs to be compiled down to ActionScript before Flash Player can do anything with it. MXML is not interpreted by Flash Player at runtime.

What you are wanting to do is not possible. Like brd6644 said, mxml is compiled down to bytecode in the swf which is interpreted by the flash player. The mxml (and even actionscript) is not understood by the flash player.
That being said, there is a JSP library that you can use for dynamic MXML. See here:
http://www.adobe.com/devnet/flex/articles/server_perf_05.html
That link is old, and right now I can't seem to find an updated link, but I know the project still exists. I believe it actually ships as part of ColdFusion still. It allows you to create dynamic mxml which gets JIT compiled at the request. It of course has a substantial performance hit because of it, but if you need dynamic MXML it is an option.
I will update this comment with a better link when I find it.

Just store the properties of the
component to a XML and put a className
attribute so that if you load the XML
you can have a function to set the
attributes of the XML to the
properties of your created component
which will be determined in your
className attribute

My initial guess is no, it would still be of type "XML", and there is no "eval" in Actionscript 3. I did a quick search and am going to have to say no, this is not possible.
I have however, done something similar in an app I created.
What I did was store in a database the object type, and some properties (x,y,width,height, etc). This data is returned from a remote object call and these objects are then created at runtime, which can get a similar effect you are trying to achieve.
For example:
var resultAC:ArrayCollection = event.result as ArrayCollection;
var tmpCanvas:Canvas;
for(var i:int = 0; i < resultAC.length; i++)
{
if(resultAC.getItemAt(i).type == "Canvas")
{
tmpCanvas = new Canvas();
tmpCanvas.x = resultAC.getItemAt(i).x;
tmpCanvas.y = resultAC.getItemAt(i).y;
...
parent.addChild(tmpCanvas);
}
}

Related

Is there a reliable way to "refresh" a component?

By "refresh" I am completely disposing it and then introducing it again in the application (without closing the application itself - that is). Other than than I think the question is self-explanatory.
Example:
Say I have a component named myComponent. I add that component to the application using MXMl in the standard way <components:myComponent id="myID" />. Say that when a user clicks a button (the button may be in another state), the component with id myID should be garbage-collected and a new instance of it added to the application.
How do I go about doing that? If there are multiple solutions which one is the optimal performance-wise?
I am new to Flash and Flex so excuse me if any incorrect terminology were used.
Remove all the event listeners from the old component; whatever they are using the removeEventListener method:
myButton.removeEventListener(someEvent, someEventHandlerMethod);
Then all variables that refer to the component should be set to null. If created in an MXML file, like this:
<s:Button id="myButton" />
Then all you have to do is set that value to null:
myButton = null;
Once there are no references to the component, it can safely become eligible for garbage collection.
If you want to re-created, then just re-created it. You'll have to re-create it in ActionScript, but the code isn't hard. Conceptually something like this:
myButton = new myButton();
myButton.properties = propertyValues;
myButton.addEventListener(someEvent, someEventHandlerMethod);
parentContainer.addChildAt(myButton, whateverPositionYouWantToADdTheComponentAt);
I'm not sure I see the benefit of doing this. I suspect it'll be much more efficient to tweak the existing button instance in the way you need to as opposed to destroying it and trying to replace it with the exact same thing.

How to add flex controls to my AS3 project?

I'm absolute newbie in Flash development but anyway I need to do something.
I have a pure AS3 project that plays video from youtube (chromeless player). I need to add some controls to manage this player. I don't know how to do that? If I just add mxml file into the project nothing happens. How to bind this file to as3?
Thanks
Flex components need to have UIComponent parent to function properly. If your player is based on Sprite, controls will not be initialized.
There is a trick to use Flex controls in the Sprite, but only after initialization in Flex Application. If you don't have Application, no luck.
You could use an AS3-only alternative. One library I've used is minimalcomps which offers some simple but effective controls for use in any AS3 project.
You can't use MXML, but nobody stops you to create your own controls if they are simple.
A short and simple example of how to add a button with an image:
loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
loader.load(new URLRequest('http://i1.nyt.com/images/misc/nytlogo379x64.gif'));
function onComplete(event:Event):void
{
var button:Sprite = new Sprite();
button.addChild(event.currentTarget.content);
addChild(button);
button.buttonMode = true;
button.addEventListener(MouseEvent.CLICK, onButtonClick);
}
function onButtonClick(event:MouseEvent):void
{
trace ('click');
}
This would be the most basic version of a button with a loaded bitmap image.
Normally you would like to check for errors as well... what to do if the image is not found, or when you're not allowed to access it.
If you're going to need more then one button you could make a class which accepts an url, so you could just pass the url to the class and the button would be created.
A completely other way to approach this is with an SWC file, you could create the buttons in the Flash IDE and export them as an swc, which you can embed and use in your pure AS3 project.

static/private child component in mxml?

Are there any way to declare a child component in mxml which is private/protected or even static?
Sure we can do this inside a script tag, but are there any other way?
Ashier suggests using the "Exclude" metadata tag, but Maskit offers its limitations and suggests alternative solutions:
http://blog.ashier.com/2008/03/25/hiding-properties-in-flex-components/
http://smaskit.blogspot.com/2008/07/making-mxml-subcomponent-private.html
In the strict meaning of these terms, no you can't do that using mxml. The second link posted by Luis contains some workarounds for private/protected behavior.
I found a solution to the static question. I wanted a quick memo pad that could be accessed anywhere in the mobile app, without one instance overwriting edits left open in a different screen.
I created a memo pad mxml control, and then placed it inside a declarations section in the top level application mxml. In each view that I wanted the memo to appear in, I added:
import mx.core.FlexGlobals;
import components.QuickMemo;
private var memo:QuickMemo;
In the view creation complete:
memo = FlexGlobals.topLevelApplication.memo;
In the viewActivation code, I added:
memo.visible = false;
addElement(memo);
In the viewDeactivation code, I included:
removeElement(memo);
The net effect is that only one instance of the memo exists at any time, and that one instance opens in whatever state it existed in the last view it appeared in.

Flex: How to call function of embedded swf?

I have a Flex 3.4 app that embeds a swf with mx:SwfLoader...
That swf has a public function named "playIt". I've tried dispatching events to gettingHere.content, casting gettingHere.content as a MovieClip and other stuff...
var swfApp:MovieClip = MovieClip(gettingHere.content);
if (swfApp.hasOwnProperty("playIt")) {
var helloWorld:Function = (swfApp["playIt"] as Function);
helloWorld();
}
to no avail. Help!
See the example here for interacting with a loaded Flex application.
Essentially:
var swfLoader:SWFLoader; // assuming loading complete
var loadedSM:SystemManager = SystemManager(swfLoader.content);
var loadedApp:Object = loadedSM.application;
app.playIt();
Are you able to load the swf into Flex at runtime rather than embed it? I've had good results loading swfs into Flex after launch, whereas embedding tends to be problematic for accessing a swf API.
Either use Loaders with eventListeners in a script or mx:SWFLoader in MXML with a listener on complete should work for you.

AS2 .swf loadmovie() and unloadmovie() fail when nested inside an AS3 .swf container

I have an AS2 .swf being loaded as a child of a parent AS3 .swf. The AS2.swf calls loadmovie() and unloadmovie() to display 3 jpeg files. The images load the first time, but after that, a call to loadmovie() to replace the image, or a call to unloadmovie() fail. I found the following Adobe Bug report (https://bugs.adobe.com/jira/browse/ASC-3338?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel) that has said this has been resolved, and also said that child movieclips could be replaced without a problem. Here is the code I'm calling.
_root.help_mc.scenes_image1_mc.loadMovie("first.jpg");
_root.help_mc.scenes_image2_mc.loadMovie("second.jpg");
_root.help_mc.scenes_image3_mc.loadMovie("third.jpg");
_root.help_mc.scenes_image1_mc.unloadMovie();
_root.help_mc.scenes_image2_mc.unloadMovie();
_root.help_mc.scenes_image3_mc.unloadMovie();
I'm not well versed in ActionScript, so I'm afraid I might not be referencing the movieclip in the correct way. The bug report said child swf's cannot replace themseleves, but if the AS2 swf is acting as the psuedo root, can I reference the movieclip through the AS2 swf?
AS2 doesn't work along-side AS3. Flash Player 9 and above have two different virtual machines - one for AS1, AS2 and the other for AS3 and only one of them is loaded at once, meaning that you can execute either AS3 or AS2 but not both.
http://en.wikipedia.org/wiki/ActionScript#Timeline_by_ActionScript_version
In ActionScript 3 you load a movie like this:
var myLoader:Loader = new Loader();
var url:URLRequest = new URLRequest("first.jpg");
myLoader.load(url);
addChild(myLoader);

Resources