2014-04-02 2 views
0

라고되고 있지 않습니다 나는 작동하는 다음 코드를 리팩토링하도록 요청했습니다 행동을 확인합니다. 이 스 니펫은 rich:dataTable 구성 요소 내부의 열에 포함됩니다. #{item}은이 버튼이있는 행에 할당 된 객체에 대한 참조입니다 (dataTable에 var="item"으로 정의 됨).콩 범위 손실 복합 JSF 구성 요소 및 활동 방법을 사용하여

재사용 할 수있는 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 대신 @ManagedBean을 사용하려고하지만

@Component("SomeViewModel") 
@ViewScoped 

, 응용 프로그램은 준 나 autowiring 오류 그래서 나는 왼쪽 @Component. 범위가 유지되었습니다. JSF와 Spring 주석의 혼합이 이런 식으로 다른 결과를 가져올 지 모른다.

그러나 SomeViewModel의 범위는 이제 괜찮 았고 f:setPropertyActionListener 대상은 설정되지 않았고 동작은 #{SomeViewController.someDeleteAction} 호출되지 않았습니다. 나는 이것을 디버깅 할 수 없었다. (중간에 무슨 일이 일어나는지 알기 위해 중단 점을 어디에 두어야할지 모르겠다.)

미리 도움을 주셔서 감사합니다.

답변

0

약간의 제안을 시도하고 나 혼자 조금 연구 한 후에 a4j:commandButtonrich:popupPanel 안에 사용할 때 어떤 종류의 문제가 있다고 결론을 냈습니다. 조치 메소드가 호출되지 않고 f:setPropertyActionListener에 정의 된 속성이 설정되지 않습니다. 나는 정확히 거기에서 길을 잃어 가고있는 것을 발견 할 수 없었다.

a4j:commandButton 팝업이 인터넷에있는 예를 보았습니다. 따라서이 문제가 내 의존성 때문에 발생하는지 확실하지 않습니다. 나는 jsf-api 2.1.19, jsf-impl 2.1.19-jbossorg-1 및 richfaces 4.3.5.Final을 사용합니다.

이것이 내가 마지막으로 한 해결책입니다.나는 내가 가진 같은 문제를 다른 사람에게 도움이 될 수 있기를 바랍니다 :

confirmButton.xhtml

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> 
<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="Some message" /> 
    <cc:attribute name="header" 
     default="Some header" /> 
    <cc:attribute name="cancelBtn" default="No" /> 
    <cc:attribute name="confirmBtn" default="Yes" /> 
    <cc:attribute name="type" default="submit" /> 
    <cc:attribute name="icon" required="false" /> 
    <cc:attribute name="image" required="false" /> 
    <cc:attribute name="action" 
     targets="popupConfirmButton" /> 
    <cc:actionSource name="confirmListeners" 
     targets="popupConfirmButton" /> 
</cc:interface> 
<cc:implementation> 
    <a4j:commandButton type="#{cc.attrs.type}" 
     image="#{cc.attrs.image}" 
     oncomplete="#{rich:component('popupConfirm')}.show()"> 
    </a4j:commandButton> 
    <a4j:commandButton id="popupConfirmButton" 
     style="visibility: hidden;" render="#{cc.attrs.render}"> 
    </a4j:commandButton> 
    <rich:popupPanel id="popupConfirm" header="#{cc.attrs.header}" 
     autosized="true" width="475" resizeable="false"> 
     <f:facet name="controls"> 
      <h:outputLink value="#" 
       onclick="#{rich:component('popupConfirm')}.hide(); return false;" /> 
     </f:facet> 
     <h:panelGrid columns="2"> 
      <h:graphicImage value="#{cc.attrs.icon}" height="64" width="64" /> 
      <p>#{cc.attrs.message}</p> 
     </h:panelGrid> 
     <br /> 
     <div align="right"> 
      <a4j:commandButton value="#{cc.attrs.confirmBtn}" 
       onclick="#{rich:element('popupConfirmButton')}.click(); 
       #{rich:component('popupConfirm')}.hide();" /> 
      &#160; 
      <h:commandButton value="#{cc.attrs.cancelBtn}" 
       onclick="#{rich:component('popupConfirm')}.hide(); return false;" /> 
     </div> 
    </rich:popupPanel> 
</cc:implementation> 
</html> 

구성 요소 사용

<my:confirmButton type="image" image="someButtonImage.gif" 
    icon="someWarningImage.gif" 
    action="#{SomeViewController.doStuff}" 
    message="Some message" 
    render="someComponentID"> 
    <f:setPropertyActionListener for="confirmListeners" 
     target="#{SomeViewModel.someProperty}" value="foo" /> 
</my:confirmButton> 
1

<f:setPropertyActionListener>은 구성 요소 ID가 아니라 ActionSource에 연결됩니다. 방법은 this answer을 참조하십시오.

편집 : 기본적으로 대신 <f:setPropertyActionListener for="buttonId">

당신은 <f:setPropertyActionListener for="source">하여에

<cc:interface> 
    <cc:actionSource name="source" targets="buttonId" /> 
    … 
</cc:interface> 
<cc:implementation> 
    <a4jcommandButton id="buttonId" … /> 
</cc:implementation> 

그리고 지점을해야합니다.

+0

내가 구현하는 방법을 잘 모르겠어요 당신의 암시. – jplatasv

+0

@NiKoLai_ 답변을 편집했습니다 – Makhiel

+0

@Makhiel, 도와 주셔서 감사합니다. 나는 이미 당신이 설명했던 것과 같은 방식으로 시도했지만, 세터가 해고되는 것도 아니고, 액션으로 정의 된 함수가 호출되지도 않는다. 완료 후에도 팝업이 닫히지 않습니다. 나는 자바 스크립트 콘솔에서이 메시지를 보면서 무언가가보기에서 사라지고 있다고 생각한다. Uncaught TypeError : undefined의 hide를 호출 할 수 없다. hide 함수는 아마도'a4j : commandButton'의'oncompletion' 속성에서 호출 된'hide' 팝업 함수 일 것입니다. 무슨 일이 일어날 지에 대한 다른 생각은 없습니까? 미리 감사드립니다. – jplatasv