Flex and JS communication and mutual adjustment between the rationale (ii) _flex

Source: Internet
Author: User
Tags eval pack

Previously wrote a flex and JS communication between the remember the beginning of the study of the two languages how to interact, flash my task is almost done, the company's Realspace products opened the JS API, but now the use of flex products are also more, the requirement to open a three-dimensional flex API, has been over the past few months, the product is also online, interested in the Https://github.com/SuperMap/Flex-Realspace can be downloaded, this is a use as and JS interaction in a complete product.

Online also have a lot of flex and JS communication articles, but do not know if you have not noticed as if you need to put the JS file in a fixed file (Flex call JS), and need to index.template.html file inside the foot, and you put the source code to the team other people, found that the Flash Builder guide in after the generation of index.template.html, but also have to modify their own, not very troublesome? If you need this technology to do their own products, I suggest you must look at the way I come up with, may help a lot of people oh!

A large project or product, in the JS code estimates will have a lot of prototypes built classes, in the flex-side estimates also have a lot of features. Our assumption is that you are using Flex production project, but some features can only be achieved through JS, so you will be part of the function using JS encapsulated into a number of JS files, I hope that through the communication between as and JS to use as language to call JS inside the function. JS file has been basically written, but because of the need to understand in a number of places in the hands of the team is not convenient, I this article is used to solve this problem.

First, Design good code

The first thing we need to understand is: JS files in the boot is loaded into the HTML page, we can pass the Externalinterface.call ("JS method", parameters), in the flex end to call the JS-side method, We can solve the method of calling the flex end in the JS end by Externalinterface.addcallback (the method named "externally disclosed").

Now we need to think: JS inside a lot of functions, we call the JS function every time we have to call the relevant methods? So the coupling between as and JS is not too high, does not conform to design patterns, and very cumbersome. The same JS here need callback (commonly used in the event callback) Flex method, a lot of methods, we are also in the flex side dynamic register so many method names? Is that not afraid of name conflict? So such an implementation is not desirable.

In order to achieve low coupling, I will be between as and JS communication between two bridges, as call JS function will always only through the call JS inside the fixed method, JS callback Flex function can only call in the program initialization of the only dynamic flex-side creation of a method. So the communication between as and JS is always only through these two methods to interact, there will not be many problems before. But I'm sure you want to know how to find out what's the difference between what I call this time and what I call next time? That's the way to tamper with the parameters. The plain thing is to judge your behavior by its parameters.

In our Flex Realspace product surface as Call JS function is through the Var result:object=externalinterface.call (" SuperMap.Web.Util.ApplicationManager.initBridgeFlexToJs ", object); SuperMap.Web.Util.ApplicationManager.initBridgeFlexToJs is in the JS end of a file inside the method, the only as access to JS channel, Special is object, this is a key value pairs, such as:

Copy Code code as follows:

var realargument:array=[strserverurl.tostring () + "$String"];
var array:object={
Action: "FUNCTION",
Key:this. KEY,
functionname: "Checkpluginupdate",
Isreturn:true,
Realargument:realargument
};

The array above is the object I'm talking about, the action in it: "FUNCTION" means the method that I need to invoke, and the key of the object being invoked is this. Key, the method name is Checkpluginupdate, there is a return value, and the method's argument is realargument (a special array).

Actually, these are kind of like JSON, used to pass data, and I custom a format is used to transfer the behavior of the operation, this you can define your own, anyway, the core is through the parameters to judge your behavior, the method always calls the same, this understanding is the design of their own things, but in the interpretation of the time a little trouble ha!

Second, packaging JS code

If your code conforms to my logic, interactive through the two bridges to communicate, then we will start next, in fact, this design has been able to make their own product interaction is very convenient, I then spent one months is doing so, have done almost, above confessed that JS code can not be opened out, And every time need to modify index.template.html file, too troublesome, hope that the flex end of the open staff can not see anything JS, require the JS file to be packaged into SWC file, by calling SWC file inside the JS to achieve the function, I was a listen to this is simply impossible! However, after a long study, found that this can be achieved, and also has its advantages.

First we need to know how to pack js file into a SWC file, a new library project, your JS files are put in, the following figure:

I built a project called Bridge, which has all of my JS files, there are many as files, careful to find every JS file next to a ... Stream.as file, here is the key, how can we pack the JS file into the SWC inside, Flex provides a flow of the way, such as the Applicationmanager.js file above, we create a class Applicationmanagerstream inherits from the FLA Sh.utils.ByteArray, the code is as follows:

Copy Code code as follows:

Package Supermap.js
{
Import Flash.utils.ByteArray;
/**
* Develop JS files and packaging methods
*/
[Embed (source= "Applicationmanager.js", mimetype= "Application/octet-stream")]
public class Applicationmanagerstream extends ByteArray
{
Public Function Applicationmanagerstream ()
{
Super ();
}
}
}

Write your corresponding JS file, be sure to and this class placed in a folder, with a packaged type Application/octet-stream, each JS file is configured with a corresponding as class, so in

It will automatically generate well packaged SWC files.

Now the problem again, inside is binary things, how we use Ah, is not our usual write as class, write what method refers to this package directly use the line.

So we also need an as class. Here I create the includestream.as code as follows:

Copy Code code as follows:

Package Supermap
{
Import SuperMap.Js.ApplicationManagerStream;
Import SuperMap.Js.HashTableStream;
Import SuperMap.Js.SceneDivStream;
Import SuperMap.lib_Ajax.IServerJava6RStream;
Import SuperMap.lib_Ajax.JsStream;
Import SuperMap.lib_Ajax.MicrosoftAjaxStream;
Import SuperMap.lib_Realspace.RealspaceStream;
/**
* This class is mainly used to get the binary form of the JS code in the form of a string
*/
public class Includestream
{
/**
* Constructor
*/
Public Function Includestream ()
{
}
/**
* Returns the string form of the code inside the JS file
*/
Public Function toString (): String
{
var microsoftajaxstream:microsoftajaxstream=new microsoftajaxstream ();
var jsstream:jsstream=new jsstream ();
var iserverjava6rstream:iserverjava6rstream=new iserverjava6rstream ();
var realspacestream:realspacestream=new realspacestream ();
var hashtablestream:hashtablestream=new hashtablestream ();
var applicationmanagerstream:applicationmanagerstream=new applicationmanagerstream ();
var scenedivstream:scenedivstream=new scenedivstream ();
Return microsoftajaxstream.tostring () +jsstream.tostring () +iserverjava6rstream.tostring () + Realspacestream.tostring () +hashtablestream.tostring () +applicationmanagerstream.tostring () + Scenedivstream.tostring ();
}
}
}

With this class, we can instantiate an object and then get all the code for JS in string form through the method ToString (). This is another problem that we still cannot use and cannot invoke. But just wrap it up and refer to your Flex project.

Third, call JS file

First we need to know as Call JS method can only call the JS form of the method, that is, embedded in the HTML page JS, and now we have only the string form of JS source code, so we need to think of ways to convert it into a standard JS code, embedded into the HTML page.

The first place to start your Flex project is the following code:

Copy Code code as follows:

Initializes a string-form method Parsestringtojs used to convert a string to a JS language
var str:string = "function Parsestringtojs (str) {var ohead = document.getElementsByTagName (' head '). Item (0);";
str+= "var oscript = document.createelement (\" script\ ");";
str+= "oscript.language =" javascript\ ";";
str+= "Oscript.type =" text/javascript\ ";";
str+= "oscript.id =" test\ ";";
str+= "Oscript.defer = true;";
str+= "oscript.text = str;";
str+= "Ohead.appendchild (Oscript);}";
Calling the Window.eval method
Externalinterface.call ("eval", str);
var includestream:includestream=new includestream ();
Get the source of the string form JS
var strey:string=includestream.tostring ();
modifying strings using regular expressions
var char:regexp =/\\/g;
Strey = Strey.replace (char, "\\\\");
Generate the JS API
Externalinterface.call ("Parsestringtojs", Strey);
Initialize JS call as the entry method Initbridgejstoflex, the final method of the implementation of the rice to transfer methods Applicationmanager.initbridgejstoflex
Externalinterface.addcallback ("Initbridgejstoflex", Applicationmanager.initbridgejstoflex);

The note has been written very clearly, but the regular expression this step can not, I am here because there is a backslash in my code things, so I was to escape, The idea here is to use Externalinterface.call to call the Window object first. Eval creates a method of converting strings into JS Code under Window Parsestringtojs, and then calls this method to convert the source code of our strings so that the HTM L in the presence of JS code, you do not have to modify the index.template.html file to add references and add a portal. And in other places you can directly call the JS-side open bridge through the Externalinterface.call, and through the Applicationmanager.initbridgejstoflex to receive JS callback function, so we only need to add SWC This package can use JS The function used.

In fact, I do not want to use Eval, eval is very consuming performance, my source code length is probably more than 80,000, fortunately, did not see the card, I will only this method, do not take a brick pat me Oh! Friends who have other ways to tell me Oh! Hope is helpful to some people!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.