[英]JSF doesn't update values in the view when f:validateRegex fails
我在 Web 應用程序中使用 JSF 2.2,當我使用 f:validateRegex 並失敗時我在視圖中遇到問題(因為當我使用 immediate="true" 並嘗試再次導航到同一頁面時,視圖是'當我的支持 bean 中有對象的新實例時不會更新)。 我在想richfaces有一個錯誤(因為我在我的主應用程序中使用jsf和richfaces)所以我用richfaces和沒有richfaces(只有jsf)做了一個測試代碼來識別錯誤在哪里,但在這兩種情況下,視圖都失敗了.
這是我沒有 Richfaces 的測試代碼(只有 jsf):
看法:
<?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-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core">
<h:head>
<title>Mis pruebas con JSF</title>
</h:head>
<h:body>
<h:form id="lista">
<h:panelGrid id="principal">
<h:dataTable value="#{indexBB.personas}" var="persona">
<h:column>
<f:facet name="header">Activo</f:facet>
<h:selectBooleanCheckbox value="#{persona.activo}"></h:selectBooleanCheckbox>
</h:column>
<h:column>
<f:facet name="header">Nombre</f:facet>
<h:outputText value="#{persona.nombre}"></h:outputText>
</h:column>
<h:column>
<f:facet name="header">Correo</f:facet>
<h:outputText value="#{persona.correo}"></h:outputText>
</h:column>
</h:dataTable>
<h:commandButton action="#{indexBB.crearPersona}" value="Crear Persona">
</h:commandButton>
<h:commandButton action="#{indexBB.activarBoton}" value="Activar Boton">
</h:commandButton>
</h:panelGrid>
</h:form>
<h:form id="crear">
<h:panelGrid id="secundario" rendered="#{indexBB.crear}">
<h:outputText value="Activo?">
</h:outputText>
<h:selectBooleanCheckbox label="Activo" value="#{indexBB.persona.activo}">
</h:selectBooleanCheckbox>
<br></br>
<h:outputText value="Nombre"></h:outputText>
<h:inputText label="Nombre" value="#{indexBB.persona.nombre}">
</h:inputText>
<br></br>
<h:outputText value="Correo"></h:outputText>
<h:inputText label="Nombre" value="#{indexBB.persona.correo}">
<f:validateRegex
pattern="[\w\.-]*[a-zA-Z0-9_]@[\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]" />
</h:inputText>
<br></br>
<h:commandButton action="#{indexBB.guardarPersona}" value="Guardar Persona">
</h:commandButton>
<h:commandButton action="#{indexBB.cancelar}" value="Cancelar" immediate="true">
</h:commandButton>
</h:panelGrid>
</h:form>
</h:body>
</html>
豆角,扁豆:
package com.kanayet.martin.view.bb;
import com.kanayet.martin.model.entity.Persona;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.inject.Named;
import javax.faces.view.ViewScoped;
@Named(value = "indexBB")
@ViewScoped
public class indexBB implements Serializable {
private Persona persona;
private List<Persona> personas;
private boolean crear;
/**
* Creates a new instance of indexBB
*/
public indexBB() {
}
@PostConstruct
public void onInit(){
personas = new ArrayList<>();
personas.add(new Persona("Martin", "martin@gmail.com", true));
personas.add(new Persona("Andrea", "andrea@gmail.com", true));
personas.add(new Persona("Camilo", "camilo@gmail.com", true));
personas.add(new Persona("Felipe", "felipe@gmail.com", true));
personas.add(new Persona("David", "david@gmail.com", true));
}
public void activarBoton() {
persona = personas.get(0);
}
public void crearPersona(){
crear = true;
persona = new Persona();
}
public void guardarPersona(){
personas.set(0, persona);
}
public void cancelar(){
}
public Persona getPersona() {
return persona;
}
public void setPersona(Persona persona) {
this.persona = persona;
}
public List<Persona> getPersonas() {
return personas;
}
public void setPersonas(List<Persona> personas) {
this.personas = personas;
}
public boolean isCrear() {
return crear;
}
public void setCrear(boolean crear) {
this.crear = crear;
}
}
模型:(對象)
package com.kanayet.martin.model.entity;
public class Persona {
private String nombre;
private String correo;
private Boolean activo;
public Persona() {
}
public Persona(String nombre, String correo, Boolean activo) {
this.nombre = nombre;
this.correo = correo;
this.activo = activo;
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public String getCorreo() {
return correo;
}
public void setCorreo(String correo) {
this.correo = correo;
}
public Boolean getActivo() {
return activo;
}
public void setActivo(Boolean activo) {
this.activo = activo;
}
}
這是我的帶有 Richfaces 的測試代碼: (Bean 和 Model 是相同的)
看法:
<?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-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
<title>Mis pruebas con RichFaces</title>
</h:head>
<h:body>
<h:form id="lista">
<a4j:outputPanel id="principal">
<rich:dataTable id="personas" value="#{indexBB.personas}"
var="persona" rows="50">
<rich:column>
<h:selectBooleanCheckbox label="Activo" value="#{persona.activo}">
</h:selectBooleanCheckbox>
</rich:column>
<rich:column>
<h:outputText value="#{persona.nombre}"></h:outputText>
</rich:column>
<rich:column>
<h:outputText value="#{persona.correo}"></h:outputText>
</rich:column>
</rich:dataTable>
<h:commandButton action="#{indexBB.crearPersona}" value="Crear Persona">
</h:commandButton>
<h:commandButton action="#{indexBB.activarBoton}" value="Activar Boton">
</h:commandButton>
</a4j:outputPanel>
</h:form>
<br></br>
<h:form id="crear">
<a4j:outputPanel id="secundario" rendered="#{indexBB.crear}">
<h:outputText value="Activo?">
</h:outputText>
<h:selectBooleanCheckbox label="Activo" value="#{indexBB.persona.activo}">
</h:selectBooleanCheckbox>
<br></br>
<h:outputText value="Nombre"></h:outputText>
<h:inputText label="Nombre" value="#{indexBB.persona.nombre}">
</h:inputText>
<br></br>
<h:outputText value="Correo"></h:outputText>
<h:inputText label="Nombre" value="#{indexBB.persona.correo}">
<f:validateRegex
pattern="[\w\.-]*[a-zA-Z0-9_]@[\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]" />
</h:inputText>
<br></br>
<h:commandButton action="#{indexBB.guardarPersona}" value="Guardar Persona">
</h:commandButton>
<h:commandButton action="#{indexBB.cancelar}" value="Cancelar" immediate="true">
</h:commandButton>
</a4j:outputPanel>
</h:form>
</h:body>
</html>
問題是當我單擊“Crear Persona”按鈕時,我寫了例如“Nombre”:Felix 和“Correo”:Felix 並單擊“Guardar Persona”按鈕,因此 f:validateRegex 失敗,因為不是有效的電子郵件,然后單擊“ Cancelar”,因為我的最終用戶不知道電子郵件所需的值(immediate="true")。 再次單擊“創建角色”按鈕,(我的 bean 中的新對象)並且 jsf 頁面沒有更新,表單應該是空的,但它不是,在字段“Nombre”中仍然是“Felix”值,但在我的 bean 中我有一個新的空對象,其屬性中沒有值,你知道為什么嗎?
問題是有和沒有richfaces(因為我認為問題可能是richfaces,但事實並非如此),所以我不知道如果我的bean中有一個新對象,為什么jsf頁面沒有更新,我使用了netbeans調試工具來驗證但我是對的,我在 bean 中看到的對象不同(服務器端新對象和空對象)但在我的 JSF 頁面中“Nombre”具有“Felix”值,我想知道為什么會發生這種情況,以及我如何解決這個問題。
非常感謝。
問題是 JSF 維護模型的兩種表示形式。 有 Java 對象 IndexBB,但也有組件樹,它用於跟蹤 UI 狀態。
當驗證失敗時,組件樹仍包含輸入的值。 (這是一個有用的功能,因此用戶可以更正這些值。)您已經使用immediate=true
跳過驗證,但這不會重置組件樹值。
在 JSF 2.2 中,您可以使用resetValues
來重置組件樹值:
<h:form id="crear">
<h:panelGrid id="secundario" rendered="#{indexBB.crear}">
<h:outputText value="Activo?">
</h:outputText>
<h:selectBooleanCheckbox label="Activo" value="#{indexBB.persona.activo}">
</h:selectBooleanCheckbox>
<br></br>
<h:outputText value="Nombre"></h:outputText>
<h:inputText id="nombreId" label="Nombre" value="#{indexBB.persona.nombre}">
</h:inputText>
<br></br>
<h:outputText value="Correo"></h:outputText>
<h:inputText id="correoId" label="Nombre" value="#{indexBB.persona.correo}">
<f:validateRegex
pattern="[\w\.-]*[a-zA-Z0-9_]@[\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]" />
</h:inputText>
<br></br>
<h:commandButton action="#{indexBB.guardarPersona}" value="Guardar Persona">
</h:commandButton>
<h:commandButton
action="#{indexBB.cancelar}" value="Cancelar">
<f:ajax resetValues="true" render="crear:nombreId crear:correoId"/>
</h:commandButton>
</h:panelGrid>
</h:form>
變化:
immediate=true
。f:ajax
添加到取消按鈕。resetValues
屬性添加到f:ajax
並列出您的 ID(用空格分隔 ID,而不是逗號)。 確保您的cancelar
方法實際上重置了persona
——您發布的代碼不會這樣做。
如果您還想重置錯誤消息,請在表單中添加一個h:messages
,給它一個 ID,然后也重置它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.