我正在设计一个使用标准 Java EE 组件(如 JSF 2.0、CDI、EJB 和 JPA)的站点。它处于早期阶段,因此导航非常简单。问题是我在导航时很难保留一些数据。
这是seminarController
支持bean:
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";
}
}
第一页目前只是列出了一些即将举行的并且可能会引起兴趣的研讨会。
index.xhtml
<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>
如您所见,我有一个带有链接的列表,如果我单击该链接,我将转到详细信息页面。我正在使用f:param
将研讨会的 ID 添加到 HTTP 请求参数中。
详细信息页面显示有关即将举行的研讨会的更多详细信息(当然)。研讨会也可以通过单击链接进行编辑。
details.xhtml
<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>
到目前为止一切顺利,一切正常。
现在我们点击链接编辑研讨会,然后进入编辑页面。我们仍在使用f:param
当前研讨会的 id。
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 按钮时,seminar
对象seminarController
是null
.
呈现编辑视图时,研讨会对象被初始化并用于显示表单中的当前值。但是当按下保存按钮时,研讨会对象不再存在于seminarController
. 并且该initSeminar
方法也没有被调用。
所以问题是我应该如何设计设计-编辑-设计页面导航?
ViewScope 不起作用,因为我在按保存时导航到新视图。无论如何使用 CDI 时 ViewScope 都不存在。
任何帮助将不胜感激!
编辑
Seminar 类有一些在表单中看不到的字段。
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
}
编辑2:
我最终在SeminarController
:
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";
}
然后我<h:inputHidden value="#{seminarController.seminarID}"/>
将edit.xhtml
.
<f:event/>
已相应更改details.xhtml
并edit.xhtml
调用该方法init()
而不是旧的initSeminar()
.
这似乎可行,尽管我不太喜欢在回发seminar
中创建对象new
,然后seminarID
在设置时将其覆盖。