从同事那里接手了flex显示工程流转的工作,最开始他做得是在html里面有按钮来触发事件从as后台获取数据,然后在前台呈现出来。这样每次修改完都要clean一下,很不舒服,于是动手把button都已到了mxml文件的内部。
但是昨天用这个的同事,跟我提了修改建议,因为我们的这个模块是作为一个部分嵌入到对方的页面里面的,所以用不着自己去触发,而是从对方那边接收参数,然后传递到后台java里面,由后台(这块儿也是由对方来完成)取出数据前台呈现
这样我需要修改的地方就是,拿到参数,并且无误的传递到后台。
初始的思路是写一个javascript函数,如下:
function runFunction(){
var type=<%=request.getParameter("type")%>;
var id=<%=request.getParameter("id")%>;
var flagname=<%=request.getParameter("flagname")%>;
//处理时有从后台获取和解析xml两种方式,通过type来做以区分
if("xml"==type){ FlowGraph.openFlowGraph(
{type:type,fileName:flagname,processId:id}); }
else{ FlowGraph.openFlowGraph({type:type,processId:id}); }
}
我想一进到这个页面就来加载这个类于是在自动生成的heml里面加入这个函数之后修改了
<body οnlοad="runFunction()">
我的mxml里面的script 函数openFlowGraph是这样写的
public function openFlowGraph(param : Object) : void
{ if(!inited) initWorkflow();
myPanelDraw.removeAllChildren();
GraphContext.getInstance().resetContext(param);
facade.sendNotification(GraphEvents.LOAD_GRAPH); }
为了调试我在runFunction()里面加入了一条alert语句,一切正常
然后就把alert语句去掉了,然后刷新页面就没有反应了,而且报对象属性未定义的错误
不知原因良久,后来终于发现了,因为我在 mxml Application里面有
creationComplete="initWorkflow()"
private function initWorkflow():void{
// pureMVC init
facade.registerCommand( GraphEvents.STARTUP, GraphStartupCommand );
facade.sendNotification( GraphEvents.STARTUP, this );
// javascript call
ExternalInterface.addCallback("openFlowGraph", openFlowGraph);
ExternalInterface.addCallback("runGraph", runGraph);
inited = true;
}
正常的执行顺序(我想得到的)应该是首先加载initWorkflow()函数,将javascript可以调用的flex的函数定义好,
然后执行runFunction,然后调用 openFlowGraph,但是现在的是页面先加载了runFunction,而此时initWorkflow()还没有正确的执行,
结果runFunction无法找到调用的flex里面的函数,但是在runFunction函数内部第一句话就加入一条alert之后,runFunction调用flex函数的时间被推迟了,
一切正常
问题了解清楚了,那我们按照正常的也就是自己想要的顺序来修改程序,首先我不是在进入到页面时就加载runFunction而是修改initWorkflow()函数
private function initWorkflow():void{
// pureMVC init facade.registerCommand( GraphEvents.STARTUP, GraphStartupCommand ); facade.sendNotification( GraphEvents.STARTUP, this );
// javascript call ExternalInterface.addCallback("openFlowGraph", openFlowGraph); ExternalInterface.addCallback("runGraph", runGraph);
//call javascript
ExternalInterface.call("runFunction");
inited = true;
}
这样就是注册了javascript可调用flex函数之后再调用runFunction
删除 openFlowGraph函数第一句,(忘记这一点了,结果是runfunction调用openFlowGraph时,因为 inited = true还没有执行就会循环调用initWorkflow函数,死锁,当然也可以将 inited = true提前到initWorkflow()的第一句,这样就不用修改openFlowGraph)修改之后代码如下:
public function openFlowGraph(param : Object) : void {
myPanelDraw.removeAllChildren();
GraphContext.getInstance().resetContext(param);
facade.sendNotification(GraphEvents.LOAD_GRAPH);
}
运行之后搞定。当然,flex默认的页面文件是html,需要修改一下扩展名变成jsp来接收request过来的参数。
说了这么一大堆,其实最初自己想要的是很清晰的,之所以犯了这样的错误就是忽略了一点,
swf在页面里面有个加载的过程,onload方法是先于里面的初始化方法执行的。低级错误,记录下来,来警界自己一下!!!