FLEX中FILEREFERENCE虽然可以弹出文件选择框,但出于安全原因无法返回文件的完整路径,就必须使用ExternalInterface与JS交互来实现。网上找到这样一种实现方法:
假设FLEX MAIN文件为MAIN.MXML,在里面SCRIPT中添加如下方法:
public function loadfile(){
ExternalInterface.addCallback("setValue",setTextValue);//让setValue成为FLEX的一个方法,setTextValue的意思是:当在网页或者其它容器里头调用Flex的setValue方法时,Flex中的 setTextValue将被调用。
ExternalInterface.call("browse");
}
public function setTextValue(val:String):void {
trace(var);
}
接着在MAIN中加入一个BUTTON,将BUTTON的onclick="loadfile()"
在MAIN.HTML中 </body>结束前添加如下代码:<input type="File" id="myFile" onchange="giveValueToFlex(myFile.value)" style="visibility:hidden" mce_style="visibility:hidden"> <script language="javascript"> function browse(){ myFile.click();//Flex所调用的browse函数就可以因此而打开浏览对话框了 } function giveValueToFlex(val){ MAIN.setValue(val);//fileField为Flex生成的HTML的swf默认id,这句话就调用fileField的setValue方法,但是,这不是Flex自带的,需要用addCallback来注册。 } </script>
运行之后我们发现已经可以实现通过文件选择框返回文件完整路径了,但是这样做有如下缺陷:
1、文件选择框弹出位置很别扭,是在左上角。
2、在这个文件选择框的基础上加入文件类型过滤器很麻烦。
3、使用IE8以下的浏览器返回结果倒没什么问题,但是如果你使用了IE8或OPREA10那恭喜你,返回的结果就是X:/FAKEPATH/XX.XXX,IE8很匪夷所思地为了所谓的安全考虑屏蔽了路径,将路径换成了"FAKEPATH"。
这些问题能解决吗?当然是可以的,而且只需要对JS部分做少许改动,上面的MAIN.HTML部分换成如下代码:
<script language="javascript"><!-- function browse(){ var fd = new ActiveXObject("MSComDlg.CommonDialog"); fd.Filter = "XML (*.xml)|*.xml";//根据需要更改你的文件过滤类型 fd.FilterIndex = 2; // 下句必须有 fd.MaxFileSize = 128; fd.ShowOpen(); giveValueToFlex(fd.filename); } function giveValueToFlex(val){ MAIN.setValue(val); } // --></script>
这段代码与上一段的区别就在于放弃使用<input type="File" id="myFile" onchange="giveValueToFlex(myFile.value)" style="visibility:hidden" mce_style="visibility:hidden">组件,而是通过ACTIVEXOBJECT调用MSComDlg.CommonDialog来实现,这样不仅可以更容易地实现文件过滤,而且弹出位置默认就是在屏幕中间的,在IE8中也可以返回正确的完整文件路径了。