JSFF或JSF頁面加載時觸發JavaScript之方法

現象一

最近在項目中遇到這麼一個問題,有些頁面元素是在頁面加載時經過JavaScript動態渲染而成。當生成這些元素的JavaScript腳本被放置於JSPX文件中時,界面渲染沒有問題。可是當咱們把生成這些頁面元素的JS腳本放到JSFF時就會發現,JS腳本只在咱們進入TaskFlow的第一個View被執行了,進入後續View時,後續View的JS代碼加載和執行。html

 
分析
經過分析,發現當進入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
 
程序員的基礎教程: 菜鳥程序員
相關文章
相關標籤/搜索