1

我在 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>

问题是当我单击“创建角色”按钮时,我写了例如“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”值,我想知道它为什么会发生,以及我如何解决这个问题。

太感谢了。

4

1 回答 1

1

问题是 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>

变化:

  1. 删除immediate=true.
  2. 将 ID 添加到要重置的输入。
  3. 添加f:ajax到取消按钮。
  4. 添加resetValues属性f:ajax并列出您的 ID(用空格分隔 ID,而不是逗号)。

确保您的cancelar方法实际重置persona- 您发布的代码不会这样做。

如果您还想重置错误消息,h:messages请在表单中添加一个,给它一个 ID,然后也重置它。

也可以看看

于 2016-04-25T23:27:57.027 回答