2012-05-28 5 views
1

JSF 2.0, CDI, EJB 및 JPA와 같은 표준 Java EE 구성 요소를 사용하여 사이트를 디자인하고 있습니다. 초기 단계이므로 탐색이 매우 간단합니다. 문제는 탐색 할 때 일부 데이터를 유지하는 데 어려움이 있습니다.범위가 지정된 페이지 탐색 요청

SeminarController.java

@Named 
@RequestScoped 
public class SeminarController { 
    @Inject 
    private SeminarDao seminarDao; 

    private int seminarID; 
    private Seminar seminar; 

    ... 
    // Getters and setters 
    ... 

    public Collection<Seminar> getSeminars() {...} 

    public Collection<Seminar> getUpcomingSeminars() {...} 

    public void initSeminar() { 
     seminar = seminarDao.findSeminar(seminarID); 
    } 

    public String save() { 
     seminarDao.save(seminar); 
     return "details"; 
    } 
} 

가 첫 번째 페이지는 현재 단지 앞으로하고 interrest이 될 수있는 몇 가지 세미나를 나열됩니다 : 여기

seminarController 백업 콩입니다.

<ul> 
     <ui:repeat value="#{seminarController.upcomingSeminars}" var="seminar"> 
      <li> 
       <h:link value="#{seminar.title}" outcome="details"> 
        <f:param name="id" value="#{seminar.seminarID}"/> 
       </h:link> 
       on 
       <h:outputText value="#{seminar.eventDate}"/> 
      </li> 
     </ui:repeat> 
    </ul> 

당신은 내가 링크를 클릭하면 세부 정보 페이지에 데려다 것 링크가있는 목록을 볼 수 있듯이

index.xhtml

. f:param을 사용하여 세미나 ID를 HTTP 요청 매개 변수에 추가합니다.

세부 정보 페이지는 다가오는 세미나에 대한 자세한 내용을 (물론) 보여줍니다. 세미나는 링크를 클릭하여 편집 할 수도 있습니다.

<f:metadata> 
    <f:viewParam name="id" value="#{seminarController.seminarID}"/> 
    <f:event type="preRenderView" listener="#{seminarController.initSeminar}"/> 
</f:metadata> 
<ui:define name="body"> 

    <h2>#{seminarController.seminar.title}</h2> 

    <p> 
     <strong>When:</strong> 
     #{seminarController.seminar.eventDate} 
    </p> 
    <p> 
     <strong>Where:</strong> 
     #{seminarController.seminar.address}, 
     #{seminarController.seminar.country} 
    </p> 
    ... 
    <p> 
     <h:link value="Edit" outcome="edit"> 
      <f:param name="id" value="#{seminarController.seminarID}"/> 
     </h:link> | 
     <h:link value="Back to List" outcome="index"/> 
    </p> 

지금까지 너무 좋아

details.xhtml

은 모든 것이 잘 작동합니다.

이제 우리는 세미나 편집 링크를 따라 편집 페이지로 이동합니다. 현재 세미나의 ID는 f:param입니다.

edit.xhtml

<f:metadata> 
    <f:viewParam name="id" value="#{seminarController.seminarID}"/> 
    <f:event type="preRenderView" listener="#{seminarController.initSeminar}"/> 
</f:metadata> 
<ui:define name="body"> 
    <h:form> 
     <h:messages title="Please correct the errors and try again."/> 
     <fieldset> 
      <h:panelGroup class="editor-label" layout="block"> 
       <h:outputLabel value="Seminar Title:" for="title"/> 
      </h:panelGroup> 
      <h:panelGroup class="editor-field" layout="block"> 
       <h:inputText id="title" value="#{seminarController.seminar.title}"/> 
       <h:message for="title" title="*"/> 
      </h:panelGroup> 
      ... 
      <p> 
       <h:commandButton value="Save" action="#{seminarController.save}"> 
        <f:param id="id" value="#{seminarController.seminar.seminarID}"/> 
       </h:commandButton> 
      </p> 
     </fieldset> 
    </h:form> 

이 나는 ​​문제가 발생하기 시작하고있는 곳입니다. Save (저장) 버튼을 누르면 세부 정보 페이지로 돌아가고 싶습니다. 세부 정보 페이지에는 새로 업데이트 된 세부 정보가 포함 된 현재 세미나가 표시됩니다. 문제는 저장 버튼을 누를 때 seminarController에있는 seminar 개체가 null 인 것입니다.

편집보기가 렌더링되면 세미나 개체가 초기화되어 양식의 현재 값을 표시하는 데 사용됩니다. 그러나 Save 버튼을 누르면 세미나 객체는 seminarController에 더 이상 존재하지 않습니다. 그리고 initSeminar 메서드도 호출되지 않습니다.

그러면 디자인 - 디자인 디자인 페이지 탐색을 어떻게 디자인해야합니까?

저장을 누르면 새로운보기로 이동하기 때문에 ViewScope가 작동하지 않습니다. 그리고 ViewScope는 CDI를 사용할 때 존재하지 않습니다.

도움이 될 것입니다.


편집

세미나 클래스는 형태로 볼 수없는 몇 가지 필드가 있습니다.

Seminar.java

@Entity 
public class Seminar { 
    @Id 
    private int seminarID; 
    @Column 
    private String title; 
    @Column 
    private Date eventDate; // Date when the seminar occurs 
    @Column 
    private Date createdDate; // Not visible in forms 
    ... 
    // Some more fields and Getters/Setters 
} 

Edit2가 :

SeminarController.java

@PostConstruct 
public void init() { 
    if (FacesContext.getCurrentInstance().isPostback()) { 
     seminar = new Seminar(); 
    } else { 
     seminar = seminarDao.findSeminar(seminarID); 
    } 
} 

public void setSeminarID(int seminarID) { 
    if (this.seminarID != seminarID) { 
     seminar = seminarDao.findSeminar(seminarID); 
     this.seminarID = seminarID; 
    } 
} 

public String save() { 
    seminarDao.save(seminar); 
    return "details?faces-redirect=true&includeViewParams=true"; 
} 
: 나는 SeminarController에서이 일을 결국

그리고 edit.xhtml<h:inputHidden value="#{seminarController.seminarID}"/>을 추가했습니다.

<f:event/>

이전 initSeminar() 대신 init() 메소드를 호출하고 details.xhtml edit.xhtml에 따라 변경되고있다.

seminar 개체가 포스트 백에서 new을 사용하여 만들어지고 나서 seminarID이 설정되면 덮어 쓰게되는 것이 좋지 않지만 작동하는 것처럼 보입니다.

답변

2

업데이트 모델 값 단계가 발생하기 전에 seminar을 직접 준비해야합니다. 프리 렌더 뷰 이벤트가 너무 늦었습니다.

하나의 방법은 현재 요청이 포스트 백인지 확인하고 Seminar을 미리 처리하여 JSF가 업데이트 모델 값 단계 중에 해당 설정자를 호출 할 수있는 기회를 갖도록하는 것입니다.

@PostConstruct 
public void init() { 
    if (FacesContext.getCurrentInstance().isPostback()) { 
     seminar = new Seminar(); 
    } 
} 

나는 initSeminar()가 무엇을 잘 모르겠어요,하지만 난 당신이 또한 그것의 일에만 if (!FacesContext.getCurrentInstance().isPostback())을한다는 것을 적절하게 변경할 필요가 있다고 생각합니다.

+0

네, 알겠습니다. 'detail.xhtml'에서'edit.xhtml'까지 갈 때 세미나 ID와 DAO를 사용하여 세미나를 인스턴스화하는 'initSeminar'를 사용하여 세미나를 만듭니다. 그리고'edit.xhtml'에서'details.xhtml'로 돌아가서 여러분이 제안한'init' 메소드에서'세미나 '를 만듭니다. 나는 그것을 밖으로 시도하고 다시 돌아올 것이다. 고맙습니다! – maba

+0

이 솔루션의 문제점은 저장을 누르면 세미나 개체가 데이터베이스에서로드 된 원래 세미나에서 온 모든 정보를 보유하지 못하는 경우입니다. 세미나 ID가 필요해 데이터베이스에서 세미나를 조회하고 값을 변경하고 다시 데이터베이스에 저장할 수 있습니다. 말이 돼? – maba

+0

''를 사용하십시오. – BalusC

관련 문제