Я разрабатываю сайт, используя стандартные компоненты Java EE, такие как JSF 2.0, CDI, EJB и JPA. Это на ранней стадии, поэтому навигация довольно проста. Проблема в том, что у меня есть трудности с сохранением некоторых данных при навигации.Запрос облачной навигации по страницам
Вот seminarController
поддержки боб:
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.
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
, чтобы добавить идентификатор семинара в параметры 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
для идентификатора текущего семинара.
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>
Это где я начинаю есть проблемы. Я хочу вернуться к странице сведений, когда нажата кнопка «Сохранить». На странице сведений должен быть показан текущий семинар с обновленной информацией. Проблема в том, что при нажатии кнопки «Сохранить» объект seminar
в seminarController
равен null
.
Когда визуализируется визуализация, объект семинара инициализируется и используется для отображения текущих значений в форме. Но когда нажата кнопка «Сохранить», объект семинара больше не существует в 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
:
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
.
The <f:event/>
был соответственно изменен в details.xhtml
и edit.xhtml
вызвать метод init()
вместо старого initSeminar()
.
Это похоже на работу, хотя я не очень нравится, что seminar
объект создается с помощью new
в пост-спине, а затем он будет перезаписан, когда seminarID
создается.
ОК, я вижу вашу точку зрения. Когда я перейду от 'detail.xhtml' к' edit.xhtml', 'семинар' будет создан с использованием моего' initSeminar', который создает экземпляр 'семинара', используя' sessionID' и DAO. И когда я возвращаюсь из 'edit.xhtml'to' details.xhtml', я создаю 'семинар' в предложенном вами методе' init'. Я попробую и вернусь. Спасибо! – maba
Проблема с этим решением заключается в том, когда я нажимаю Сохранить объект семинара не содержит всю информацию, полученную из исходного семинара, загруженного из базы данных. Мне нужен семинарID, чтобы я мог найти семинар из базы данных и изменить значения и сохранить обратно в базу данных. Имеет ли это смысл? – maba
Используйте ' '. –
BalusC