現象一
最近在項目中遇到這么一個問題,有些頁面元素是在頁面加載時通過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
程序員的基礎教程:
菜鳥程序員