java - preRenderView 禁用ajax

标签 java jsf jsf-2

<ui:composition template="/WEB-INF/templates/base.xhtml"
                xmlns="http://www.w3.org/1999/xhtml"
                xmlns:ui="http://java.sun.com/jsf/facelets"
                xmlns:h="http://java.sun.com/jsf/html"
                xmlns:f="http://java.sun.com/jsf/core"
                xmlns:p="http://primefaces.org/ui">    
    <ui:define name="metadata">
        <f:metadata>
            <f:event type="preRenderView" listener="#{resetPassword.loadUser}" />
            <f:viewParam name="user" value="#{resetPassword.user}" />
        </f:metadata>
    </ui:define>

    <ui:define name="content">
        <h:form rendered="#{resetPassword.user != null}">
            <h:panelGrid class="form_panel" columns="2" width="596px">
                <h:outputLabel class="form_label" for="password" value="#{base['resetPassword.password']}" />
                <h:inputSecret class="form_inputText" id="password" value="#{resetPassword.password}">
                    <f:ajax event="keyup" execute="password" listener="#{resetPassword.validatePassword}" render="scorePanel complexity" />
                </h:inputSecret>

                (...) // Other labels and inputfields, no ajax
            </h:panelGrid>
        </h:form>
    </ui:define>
</ui:composition> 

我已经阅读了关于 preRenderView 的很多问题结合 ajax - 电话。我遇到的主要问题是 postback问题。不过,就我而言,ajax preRenderView 根本不会触发.无整f:event -标签,我的ajax -调用确实工作正常。

resetPassword.loadUser()将设置 resetPassword.user ,这不是空的。我需要使用 preRenderView而不是 @PostConstruct为了填写f:viewParam .提交表单时需要此参数。

为什么我的 ajax -事件中断时 <f:event type="preRenderView" />定义了吗?

注意:<ui:insert name="metadata" />在模板里面位于<h:head> .

更新

正如 BalusC 评论的那样,该问题在这部分代码中不可见。

public void loadUser(ComponentSystemEvent event) {
    if(!FacesContext.getCurrentInstance().isPostback()) {
        user = (hash != null) ? userService.getByIdAndPwdResetHash(userId, hash) : null;
    }
}

此代码可能返回 null但没有(因为正在加载我的表单)。

public void validatePassword(AjaxBehaviorEvent event) {
    System.out.println("Ajax works"); // Just for testing purposes so far
}

我不知道要进一步添加什么,因为这几乎是所有相关代码。

最佳答案

此构造将在 #{resetPassword} 时失败是请求范围和 user属性在 bean 的(后期)构造期间未初始化。

JSF 将在应用请求值阶段即重新评估 rendered在处理提交的值之前输入组件(这也包括它的所有父组件)的属性,作为防止篡改请求的一部分。在您的情况下,不会呈现父表单,因此不会处理所有输入组件。

您基本上有 2 个选择:

  1. 制作 bean @ViewScoped (或 CDI 等价物 @ConversationScoped )。这样,只要您与同一 View 交互(相应对话),它就会一直存在。

  2. 执行 user 的初始化在(后)构造函数中。预渲染 View 为时已晚。由于您的 bean 已经在请求范围内,因此只需使用 @ManagedProperty (或其本土 CDI 等价物;谷歌在“@HttpParam”上有结果)。

另见:


与具体问题无关,在 action(listener) 方法中执行验证不是正确的方法。而不是 <f:ajax listener> , 使用正常 Validator您通过输入组件的 validator 引用它属性或嵌套 <f:validator> .

关于java - preRenderView 禁用ajax,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13570301/

相关文章:

jsf - 部署 JSF webapp 导致 java.lang.ClassNotFoundException : javax. servlet.jsp.jSTL.core.Config

java - jsf2 + <托管属性> <属性名称>

java - System.out.println() 更改单线程程序中变量的值

javascript - 当 Primefaces 全局计数器递增时,为什么我看不到任何网络流量?

java - 如果PreparedStatement可以提高性能,为什么还要使用Statement

jsf - 用户界面 :repeat doesn't work with Map

java - 使用 jquery ajax 调用托管 bean 方法并在 jquery 中取回结果

java - 菜单错误的解决方法

java - 自行设计类中的arraylist错误。请帮我

java - 创建未知类型的数组