考慮一個簡單的H:outputText組件:JSF懶加載組件值
<h:outputText value="#{myBean.myValue}"/>
我怎麼能延遲加載該頁面後,價值已經呈現,並且代替值,同時顯示自定義「AJAX加載」圖標這是正在完成?
我在我的項目中使用PrimeFaces 3.5,所以任何PF特定的實現將受到歡迎。
考慮一個簡單的H:outputText組件:JSF懶加載組件值
<h:outputText value="#{myBean.myValue}"/>
我怎麼能延遲加載該頁面後,價值已經呈現,並且代替值,同時顯示自定義「AJAX加載」圖標這是正在完成?
我在我的項目中使用PrimeFaces 3.5,所以任何PF特定的實現將受到歡迎。
建議在頁面加載後(通過將autoRun
屬性設置爲true)調用remoteCommand
並更新outputText
來完成此操作。
private String myValue;
// getter and setter
public void initMyValue() {
// init myValue
}
在頁面上,你應該有ajaxStatus
組件用於查看加載圖像,和你的outputText
。還應該有p:remoteCommand
組件:
<p:ajaxStatus style="width:16px;height:16px;" id="ajaxStatusPanel">
<f:facet name="start">
<h:graphicImage value="ajaxloading.gif" />
</f:facet>
<f:facet name="complete">
<h:outputText value="" />
</f:facet>
</p:ajaxStatus>
<h:outputText id="myText" value="#{myBean.myValue}"/>
<p:remoteCommand autoRun="true" actionListener="#{myBean.initMyValue}" update="myText"/>
編輯:我應該要的outputText
延遲加載的價值,因爲它包含了一些長時間運行的計算,但如果你想的outputText
完全deffer呈現先加boolean
在你的後臺bean的屬性,將此屬性設置爲true
在initMyValue
方法的末尾:
private boolean loaded;
// getter and setter
public void initMyValue() {
// init myValue
loaded = true;
}
在頁面上重新組織如下:
<h:panelGroup id="myPanel" layout="block">
<h:graphicImage value="ajaxloading.gif" rendered="#{!myBean.loaded}"/>
<h:outputText value="#{myBean.myValue}" rendered="#{myBean.loaded}"/>
</h:panelGroup>
<p:remoteCommand autoRun="true" actionListener="#{myBean.initMyValue}" update="myPanel"/>
您可以使用BlockUI在加載組件時有條件地阻止該組件。
定義在<h:outputText/>
<h:outputText id="myText">
<f:event name="preRenderComponent" id="started"/>
</h:outputText>
一個preRenderComponent
事件定義<p:blockUI/>
與事件的ID作爲觸發
<p:blockUI block="myText" trigger="started" />
您可以自定義blockui到顯示圖像或其他。
謹慎的一句話:我認爲你需要這個,因爲你在這個組件的getter中做了一些繁重的工作。知道getter將在該頁面的生命週期中多次調用。因此隱瞞手術花費很長時間的事實不會改變事實。一個更好的設計將是在一個持久的範圍內預加載和緩存該組件的值,而不是「加載」跳動者的表演。
嘗試過,但在我的頁面顯示給用戶之前調用preRenderComponent事件偵聽器。這是一個模態動態的PF對話框 - 想知道這與它有什麼關係?此外,我完全理解你在緩存持久範圍中的值時所說的話 - 在這種情況下,我有API調用來將IP地址解析爲位置,並且由於API調用的數量有限,我寧願不這樣做,除非用戶真正查看數據。 – rootkit 2013-03-14 14:52:18
@rootkit,現在有更好的上下文,我可以建議一個更合適的解決方案。在對話框中設置'dynamic =「true」'來阻止加載頁面時加載對話框的內容。此外,可以使outputText的'rendered'屬性有條件,以確保該元素僅在需要時才放入DOM中 – kolossus 2013-03-14 15:11:57
該對話框已經是動態的,但我多次顯示它。我只想在用戶打開對話框時查找位置,並且由於查找需要好幾秒鐘,我不想延遲打開對話框...... – rootkit 2013-03-14 16:14:22
這是我怎麼會實現它:
<h:panelGroup id="loginLocation">
<p:graphicImage library="assets" name="small-kit-loader.gif" width="16" height="16" rendered="#{empty mybean.lastLoginLocation}"></p:graphicImage>
<h:outputText value="#{myBean.lastLoginLocation}" rendered="#{!empty myBean.lastLoginLocation}"/>
</h:panelGroup>
<p:remoteCommand global="false" actionListener="#{actionBean.getUserLoginLocation(myBean.selectedUser)}" name="refreshLoginLocation" id="rc1" autoRun="true" update="loginLocation" process="@this"></p:remoteCommand>
個人我不是這個實現完全滿意:
歡迎任何有關如何改進此代碼的建議! :)
看起來像它會工作,但也意味着myText將在頁面呈現期間急切加載。我怎樣才能避免這種情況?我意識到我可以在後臺bean中做到這一點,但只要延遲加載就好了。此外,在這種情況下,ajaxStatus將是全局的 - 我只想顯示一個加載狀態來代替專門爲此組件設置的值。謝謝! – rootkit 2013-03-13 16:28:05
我編輯了一個答案。我添加了可能更適合您需求的部分。 – partlov 2013-03-14 07:48:24
是的,這經過一些調整後才起作用。儘管如此,對於這樣一個簡單的任務來說,上述所有方面都是太麻煩了。沒有更優雅的解決方案嗎?我會寫一個組件來做懶惰的渲染...... – rootkit 2013-03-14 16:27:14