jsf immediate=“true” относительно привязки к сеансовому компоненту
-
23-09-2019 - |
Вопрос
У меня есть страница со списком это относится к добавить страницу.На странице добавления есть текстовое поле имени значение которого привязано к компонент с областью действия сеанса.
Страница со списком содержит кнопка добавить это переходит через метод действия на страницу добавления.Этот метод действия очищает объект, к которому привязано текстовое поле name.
У меня также есть кнопка отмены на странице добавления, которая привязана к методу действия, который снова очищает значение, к которому привязано текстовое поле name.
Если ничего не установлено в значение immediate, все это работает нормально.
Однако, если я установлю для кнопки отмены значение immediate, если я введу значения в поле name, а затем нажму cancel, метод action будет запущен и очистит объект в вспомогательном компоненте и перейдет на страницу со списком.Если я затем нажму добавить, метод action снова очистит объект (игнорируйте, лучший это метод или нет), а затем перейдет на страницу добавления.Теперь я бы ожидал, что текстовое поле "Добавить название страницы" будет пустым, но это не так?!Конечно, поскольку кнопка добавить не является немедленной, значения должны быть повторно привязаны и пусты?
Ниже приведен соответствующий XHTML для кнопки добавить на странице со списком
<h:commandButton id="addButton"
value="Add"
action="#{myBean.gotoAdd}"/>
Ниже приведен соответствующий XHTML для поля ввода на странице добавления (MyBean ограничен областью сеанса), за которым следует XHTML кнопки отмены на странице добавления.:
<h:inputText id="newName"
value="#{myBean.newObject.name}"
binding="#{myBean.newNameInput}"
styleClass="name" />
<h:commandButton id="cancelButton"
value="Cancel" immediate="true"
action="#{myBean.cancelAdd}"
onclick="return confirm('You sure?');"/>
Решение
Я почти никогда не пользуюсь binding
свойство тегов, за исключением случаев, когда мне нужно определить, к какому элементу списка было применено действие, поэтому я не особенно хорошо информирован о его использовании.Но я знаю, что без использования binding
ваш код, скорее всего, будет работать так, как вы ожидали, поэтому я ожидаю, что независимо javax.faces.component.UIxxx
объект, к которому вы привязываетесь, неправильно сбрасывается.
Другие советы
У меня сейчас очень похожие проблемы.
Помимо удаления привязки и / или атрибута immediate, попробуйте вызвать setSubmittedValue() для компонента с привязкой из действия, вызываемого при нажатии на кнопку "добавить".
Увы, даже если это поможет вам, вам все равно придется делать это при любом действии, которое может привести к отображению того же компонента после отмены.
Вот почему я все еще пытаюсь найти какое-нибудь лучшее решение...
Если вы используете immediate="true", то значение будет сохранено, вот как работает параметр.Вам следует ознакомиться со следующими ссылками:
http://wiki.apache.org/myfaces/How_The_Immediate_Attribute_Works
Хорошо, вот пример, который я сделал с нуля.У меня есть две кнопки отмены, одна из которых действует немедленно, а другая - нет.Пример шагов для воспроизведения:
- Перейдите на страницу james-list и нажмите Добавить
- Откроется страница добавления с пустыми полями.Введите значения для всех полей и нажмите Добавить.
- Страница со списком отображается и обновляется для включения нового пользователя.Нажмите Добавить.
- Откроется страница добавления с пустыми полями.Введите значения для всех полей и нажмите "Отмена" (немедленно).
- Страница со списком отображается без изменений.Нажмите Добавить.
- Страница добавления отображается, однако поля не пустые, как я ожидал бы.Нажмите кнопку Отмена.
- Страница со списком отображается без изменений.Нажмите Добавить.
- Откроется страница добавления, и ТЕПЕРЬ поля не пустые.
James.java:
package com.jamiebarrow;
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.component.UIComponent;
@ManagedBean
@SessionScoped
public class James {
private UIComponent idComponent;
private UIComponent firstNameComponent;
private UIComponent lastNameComponent;
public UIComponent getIdComponent() {
return idComponent;
}
public void setIdComponent(UIComponent idComponent) {
this.idComponent = idComponent;
}
public UIComponent getFirstNameComponent() {
return firstNameComponent;
}
public void setFirstNameComponent(UIComponent firstNameComponent) {
this.firstNameComponent = firstNameComponent;
}
public UIComponent getLastNameComponent() {
return lastNameComponent;
}
public void setLastNameComponent(UIComponent lastNameComponent) {
this.lastNameComponent = lastNameComponent;
}
private List<Person> personResults;
private Person person;
public James() {
personResults = new ArrayList();
personResults.add(new PersonBuilder(1, "Bob", "Uncle").build());
personResults.add(new PersonBuilder(2, "Jack", "Black").build());
}
public List<Person> getPersonResults() {
return personResults;
}
public void setPersonResults(List<Person> personResults) {
this.personResults = personResults;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
private void clearPerson() {
person = new PersonBuilder().build();
}
public String gotoList() {
return "james-list";
}
public String gotoAdd() {
clearPerson();
return "james-add";
}
public String cancelAdd() {
clearPerson();
return gotoList();
}
public String addPerson() {
personResults.add(person);
return gotoList();
}
}
джеймс-список.xhtml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>list page</title>
</h:head>
<body>
<div class="container">
<div class="content">
<h:messages showSummary="true" showDetail="false" errorClass="error" infoClass="info"
warnClass="warn"/>
<h:form>
<h:dataTable value="#{james.personResults}" var="person">
<h:column>
<f:facet name="header">Id</f:facet>
<h:outputText value="#{person.id}"/>
</h:column>
<h:column>
<f:facet name="header">Name</f:facet>
<h:outputText value="#{person.firstName}"/>
</h:column>
<h:column>
<f:facet name="header">Surname</f:facet>
<h:outputText value="#{person.lastName}"/>
</h:column>
</h:dataTable>
<h:panelGroup layout="block">
<h:commandButton value="Add" action="#{james.gotoAdd}"/>
</h:panelGroup>
</h:form>
</div>
</div>
<ui:debug hotkey="L" rendered="true"/>
</body>
</html>
джеймс-добавить.xhtml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>add page</title>
</h:head>
<body>
<div class="container">
<div class="content">
<h:messages showSummary="true" showDetail="false" errorClass="error" infoClass="info"
warnClass="warn"/>
<h:form>
<fieldset>
<legend>Add Person</legend>
<h:panelGrid columns="2">
<h:outputLabel for="PersonId" value="Id:"/>
<h:inputText id="PersonId" value="#{james.person.id}" binding="#{james.idComponent}"/>
<h:outputLabel for="PersonFirstName" value="First Name:"/>
<h:inputText id="PersonFirstName" value="#{james.person.firstName}" binding="#{james.firstNameComponent}"/>
<h:outputLabel for="PersonLastName" value="Last Name:"/>
<h:inputText id="PersonLastName" value="#{james.person.lastName}" binding="#{james.lastNameComponent}"/>
</h:panelGrid>
<h:panelGroup layout="block">
<h:commandButton value="Add" action="#{james.addPerson}"/>
<h:commandButton value="Cancel (immediate)" action="#{james.cancelAdd}" immediate="true"/>
<h:commandButton value="Cancel" action="#{james.cancelAdd}"/>
</h:panelGroup>
</fieldset>
</h:form>
</div>
</div>
<ui:debug hotkey="L" rendered="true"/>
</body>
</html>