• JSFF或JSF页面加载时触发JavaScript之方法


    现象一

    最近在项目中遇到这么一个问题,有些页面元素是在页面加载时通过JavaScript动态渲染而成。当生成这些元素的JavaScript脚本被放置于JSPX文件中时,界面渲染没有问题。但是当我们把生成这些页面元素的JS脚本放到JSFF时就会发现,JS脚本只在我们进入TaskFlow的第一个View被执行了,进入后续View时,后续View的JS代码加载和执行。

     
    分析
    通过分析,发现当进入TaskFlow的第一个View时,第一个View中通过<af:resource/>标签引入的JS代码能成功被添加到页面上,而且页面的onload事件也被执行,所以页面元素渲染成功。
    但是当从第一个View流转到后续View时,后续View中通过<af:resource/>标签引入的JS代码则没有被加入页面中,所以页面元素都无法渲染。但是如果此时我们刷新页面,页面上的元素又能正确展现。这是因为刷新后ADF重新生成页面的HTML代码,重新解析了后View中的<af:resource/>标签,并将相关的代码引入页面。
     
    解决
    在<af:resource/>标签外套用<af:panelGroupLayout/>,这样resource就会每次都被包含到页面中。
     
    现象二
    解决了上一个问题,现在TaskFlow中所有View在展现时,JavaScript代码都能正确地被引入页面,并被执行以正确地生成页面元素。但是很快我发现了另外一个问题,那就是JavaScript代码只能在第一次展示View时成功被调用。如果我们从一个View流转到另一个View,然后再次流转回来的话,onload事件的JavaScript就不会被执行了。
     
    分析
    ADF渲染了某个View后,该View就会有缓存,再次访问时就不会再次渲染并触发onload事件。我尝试设置了TaskFlow的Refresh配置,但是无果。
     
    问题的关键是现在无法保证每次进入View时都能触发onload事件,既然客户端脚本不行,那么是否能够通过服务端的方式在页面加载时激活相应的JavaScript代码进行元素的渲染呢?使页面在加载时能触发后台的一个Java方法,然后在Java方法内触发JS方法(关于如何在Java中调用JS,请参考我的这篇文章)。按照这个思路,我们可以通过在页面添加Executable来实现。通过搜索我发现网上的确也有人遇到类似的问题,并通过这种方法解决。但是通过Executable来实现有个缺点,就是需要生成自定义的Java Bean Data Control以及配置起来比较繁琐(需要为每个页面配置Method Binding以及Executable)。
     
    解决
    经过不断的尝试,最后,我想到了一个简化的方法:
    1. 在View中添加一个<af:outputText/>标签;
    2. 将<af:outputText/>的Value绑定到一个bean的属性#{myBean.dummy};
    3. 其实,无需在myBean中定义dummy属性,只需定义一个getDummy()方法,并在其中添加调用JS代码的逻辑;
     
    每当JSFF展现时ADF会重新执行所有的EL表达式,包括#{myBean.dummy},这样在getDummy()中的逻辑就会被执行,相应的JS方法也会被调用。这样我们的需求就实现了。但是,我觉得将JS的调用逻辑完全放在Bean中完成可能会比较死板。如果我们需要更改调用JS的逻辑,就必须要修改Bean的方法。最后我将调用JS的逻辑进行修改,使其调用脚本内容指向前台<af:outputText/>标签的shortDesc属性:
        private RichOutputText scriptSetting; //OutputText的binding变量
     
        public String getDummy() {
            String script = scriptSetting == null ? "" : scriptSetting.getShortDesc(); //获取脚本内容
            invokeJavaScript(script);//调用JS
            return "";
        }
     
    以后如果某个页面需要在加载时调用JS脚本,只需要做下面3步:
    1. 在TaskFlow中注册myBean;
    2. 在页面中放置如下代码;
    <af:outputText  shortDesc="youJSFunction();" 
                       value="#{myBean.dummy}" id="scriptControl"
                       binding="#{myBean.scriptSetting}"/>
    3. 修改shortDesc属性值为所需要的JS代码。
     
    示例的源代码请在这里下载,所使用的JDeveloper版本为11.1.1.6.0。
     
    只要思想不滑坡,办法总比问题多 :)元芳,你怎么看?
     
    转载自:http://blog.sina.com.cn/s/blog_671b3b1001018vr3.html
     
    程序员的基础教程:菜鸟程序员
  • 相关阅读:
    黄聪:C#多线程教程(1):BeginInvoke和EndInvoke方法,解决主线程延时Thread.sleep柱塞问题(转)
    黄聪:C#类似Jquery的html解析类HtmlAgilityPack基础类介绍及运用
    黄聪:国内com域名转移到Godaddy详细教程(转)
    黄聪:Navicat for MySQL的1577错误解决
    黄聪:VPS配置Filezilla Server支持FTP的Passive被动模式(FTP连接不上怎么办?有详细教程)
    黄聪:Microsoft office 2013版下载、安装及破解工具下载破解教程(Windows Toolkit)
    黄聪:mysql搬家,直接复制data文件夹(*.MYD,*.MYI,innodb)出错,无法正常显示
    黄聪:WordPress默认编辑器可视化切换不见了,非插件导致消失问题
    黄聪:自定义WordPress顶部管理工具条的技巧(转)
    黄聪:VS2010中“新建项目”却没有“解决方案”节点,如何调出来
  • 原文地址:https://www.cnblogs.com/guohu/p/3951665.html
Copyright © 2020-2023  润新知