现象一

最近在项目中遇到这么一个问题,有些页面元素是在页面加载时通过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
 
程序员的基础教程:菜鸟程序员

JSFF或JSF页面加载时触发JavaScript之方法的更多相关文章

  1. JSP在页面加载时调用servlet的方法

    方法:先在JS里面写一个调用servlet的事件(可以利用ajax),然后利用<body>标签的onload调用这个事件. 代码如下: jsp文件代码如下: <%@ page lan ...

  2. 页面加载时调用js函数方法

    方法一:在html的body中加入onload=""事件 <body onload='queryServer()'> </body> 方法二:jquery ...

  3. Javascript在页面加载时的执行顺序【转】

    一.在HTML中嵌入Javasript的方法 直接在Javascript代码放在标记对<script>和</script>之间 由<script />标记的src属 ...

  4. ASP.NET中页面加载时文本框(texbox控件)内有文字获得焦点时文字消失

    代码如下: <asp:TextBox ID="TextBox1" runat="server" Height="26px" MaxLe ...

  5. 使用 v-cloak 防止页面加载时出现 vuejs 的变量名

    使用 vuejs 做了一个简单的功能页面,逻辑是,页面加载后获取当前的经纬度,然后通过 ajax 从后台拉取附近的小区列表.但是 bug 出现了,在显示小区列表之前,会闪现小区名对应的 vuejs 变 ...

  6. 解决JS文件页面加载时的阻塞

    关于页面加载时的时间消费,许多书中都做出了介绍,也提出了很多种方法.本文章就详细介绍XHR注入. 概述:JS分拆的方法 1.XHR注入:就是用ajax异步请求同域包含脚本的文件,然后将返回的字符串转化 ...

  7. 页面加载时,页面中DIV随之滑动出来;去掉页面滚动条

    <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8&quo ...

  8. jquery--blur()事件,在页面加载时自动获取焦点

    jquery--blur()事件会在页面加载时自动获取焦点,应将onblur写到html标签中 <div class="inputbox"> <input typ ...

  9. 使用 v-cloak 防止页面加载时出现 vue.js 的变量名

    知识点:使用 v-cloak 防止页面加载时出现 vue.js 的变量名 场景:在使用vue语法,实现下拉框功能时,展示数据列表之前,出现对应的 vuejs 变量名 代码: var vm = new ...

随机推荐

  1. CI框架的引导流程以及基准测试类

    一[CI]框架的引导流程了解一下,并掌握如何新增自己的扩展类库   http://www.cnblogs.com/ohmygirl/p/CIRead-4.html // CI框架源码阅读笔记4 引导文 ...

  2. Redis学习笔记-事务控制篇(Centos7)

    一.事务控制 1.简单事务控制 redis可以使用mult命令将之后的命令都存放在队列中,只有使用exec命令时才全部执行. 127.0.0.1:6379> multi OK 127.0.0.1 ...

  3. TCP/IP分析

    TCP/IP四层模型 TCP/IP参考模型 ISO制定的OSI参考模型的过于庞大.复杂招致了许多批评.与此对照,由技术人员自己开发的TCP/IP协议栈获得了更为广泛的应用.如图2-1所示,是TCP/I ...

  4. TimescaleDB 简单试用

    TimescaleDB 是一个对于pg进行了改造的时序数据库 安装测试使用docker 安装&&运行 docker run -d --name timescaledb -p 5432: ...

  5. const_cast

    函数原型: const_cast < type-id > ( expression ) 去掉const属性:const_cast<int*> (&num),常用,因为不 ...

  6. Phonegap 原生控件(Android)与html混合

    1. 用命令创建cordova项目 cordova coreate hello com.example.hello hello 2.打开MainActivity 在onCreate方法中加入 setC ...

  7. 黄聪:“不允许对64位应用程序进行修改”的解决方法 --“Changes to 64-bit applications are not allowed.”

    在64位系统中使用VS对程序(32位的)进行调试,出现“不允许对64位应用程序进行修改”的提示,如下图所示: 解决方法:在VS主菜单上选择“生成” or "Build"——“配置管 ...

  8. genmotion 安装 app 报错 This application is't compatible with your mobile phone解决办法

    请下载这个文件:http://pan.baidu.com/s/1jIyMNbg(一个zip包) 将这个zip包拖放到genymotion的屏幕中,安装,然后重启就行了 我安装的Samsung Gala ...

  9. Java 运用流传输文件

    实例1 package IO; import java.io.FileReader; import java.io.FileWriter; import java.io.Reader; import ...

  10. Jenkins构建Python项目提示:'python' 不是内部或外部命令,也不是可运行的程序

    问题描述: jenkin集成python项目,立即构建后,发现未执行成功,查看Console Output 提示:'Python' 不是内部或外部命令,也不是可运行的程序,如下图: 1.在 Windo ...