我一直在問重構下面的代碼,它的工作原理:豆範圍損失從未被稱爲
<a4j:commandButton type="image"
image="/someImage.gif"
action="#{SomeViewController.someDeleteAction}"
onclick="return confirm('#{msg['a.message']}');"
render="someDataTableWithItems">
<f:setPropertyActionListener
target="#{SomeViewModel.selectedItem}" value="#{item}" />
</a4j:commandButton>
..to它允許使用自定義彈出替代確認行動。該片段嵌入在rich:dataTable
組件內的列中。 #{item}
是分配給此按鈕所在行的對象的引用(在dataTable中定義爲var="item"
)。
我決定做一個JSF複合組件(我的第一個組件)有一些我可以重用的東西。它基於此answer by elias
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich"
xmlns:cc="http://java.sun.com/jsf/composite">
<cc:interface>
<cc:attribute name="message" default="#{msg['a.default.message']}" />
<cc:attribute name="header"
default="#{msg['a.default.header']}" />
<cc:attribute name="action" required="true"
method-signature="java.lang.String action()" />
<cc:attribute name="actionListener" required="false"
method-signature="java.lang.String action()" />
<cc:attribute name="value" default="Send" />
<cc:attribute name="cancelBtn" default="#{msg['a.default.cancel']}" />
<cc:attribute name="confirmBtn" default="#{msg['a.default.ok']}" />
<cc:attribute name="render" default="@form" />
<cc:attribute name="type" default="submit" />
<cc:attribute name="image" required="false"/>
<cc:attribute name="tooltip" required="false" />
</cc:interface>
<cc:implementation>
<a4j:commandButton type="#{cc.attrs.type}" rendered="#{empty cc.attrs.actionListener and not empty cc.attrs.image}"
image="#{cc.attrs.image}" value="#{cc.attrs.value}"
oncomplete="#{rich:component('somePopup')}.show()">
<rich:tooltip followMouse="false" showDelay="1000" rendered="#{not empty cc.attrs.tooltip}">
#{cc.attrs.tooltip}
</rich:tooltip>
</a4j:commandButton>
<a4j:commandButton type="#{cc.attrs.type}" rendered="#{not empty cc.attrs.actionListener and not empty cc.attrs.image}"
actionListener="#{cc.attrs.actionListener}"
image="#{cc.attrs.image}" value="#{cc.attrs.value}"
oncomplete="#{rich:component('somePopup')}.show()">
<rich:tooltip followMouse="false" showDelay="1000" rendered="#{not empty cc.attrs.tooltip}">
#{cc.attrs.tooltip}
</rich:tooltip>
</a4j:commandButton>
<a4j:commandButton type="#{cc.attrs.type}" rendered="#{empty cc.attrs.actionListener and empty cc.attrs.image}"
value="#{cc.attrs.value}"
oncomplete="#{rich:component('somePopup')}.show()">
<rich:tooltip followMouse="false" showDelay="1000" rendered="#{not empty cc.attrs.tooltip}">
#{cc.attrs.tooltip}
</rich:tooltip>
</a4j:commandButton>
<a4j:commandButton type="#{cc.attrs.type}" rendered="#{not empty cc.attrs.actionListener and empty cc.attrs.image}"
actionListener="#{cc.attrs.actionListener}" value="#{cc.attrs.value}"
oncomplete="#{rich:component('somePopup')}.show()">
<rich:tooltip followMouse="false" showDelay="1000" rendered="#{not empty cc.attrs.tooltip}">
#{cc.attrs.tooltip}
</rich:tooltip>
</a4j:commandButton>
<rich:popupPanel id="somePopup"
header="#{cc.attrs.header}" autosize="true" resizeable="false">
<p>#{cc.attrs.message}</p>
<a4j:commandButton action="#{SomeViewController.someDeleteAction}" <!-- It should be #{cc.attrs.action} but I just put this for debug -->
value="#{cc.attrs.confirmBtn}" render="#{cc.attrs.render}"
oncomplete="#{rich:component('somePopup')}.hide()">
<cc:insertChildren />
</a4j:commandButton>
<h:commandButton value="#{cc.attrs.cancelBtn}"
onclick="#{rich:component('somePopup')}.hide(); return false;" />
</rich:popupPanel>
</cc:implementation>
</html>
..和取代先前a4j:commandButton
本:
<my:buttonConfirm type="image" id="someID"
image="/someImage.gif"
action="#{SomeViewController.someDeleteAction}"
message="#{msg['a.confirmation.message']}"
render="someDataTableWithItems"
tooltip="#{msg['a.tooltip.message']}">
<f:setPropertyActionListener for="someID"
target="#{SomeViewModel.selectedItem}" value="#{item}" />
</my:buttonConfirm>
的彈出窗口,你可以取消行動,但它確認時,SomeViewModel再次重新實例化,失去範圍中的前一個bean。
範圍是自定義視圖範圍從here
了後來我改變了模型的範圍,這一個:
@Component("SomeViewModel")
@ViewScoped
雖然我試圖用@ManagedBean
代替@Component
,應用了我自動裝配錯誤,所以我離開了@Component
。範圍現在保留。 我不知道在這種方式下JSF和Spring註釋的混合是否會產生其他後果。
然而SomeViewModel
範圍現在是精細,f:setPropertyActionListener
目標從未設定和動作#{SomeViewController.someDeleteAction}
從未被調用。我一直無法調試(不確定在哪裏放置斷點來查看中間發生了什麼)。
在此先感謝您的幫助。
我不知道如何實現您建議。 – jplatasv
@NiKoLai_我編輯了答案 – Makhiel
感謝您的幫助,@Makhiel。我已經嘗試了與你解釋的相同的方式,但是這兩個設置者都沒有被解僱,也沒有被定義爲動作的函數被調用。完成後,彈出窗口甚至沒有關閉。我認爲有些東西在視圖中迷失了,因爲我在javascript控制檯上看到這條消息:'Uncaught TypeError:無法調用方法'隱藏'未定義'。該隱藏函數可能是在'a4j:commandButton'的'oncompletion'屬性上調用的'hide'彈出函數。任何其他的想法可能會發生什麼?提前致謝。 – jplatasv