JSF Ajax Invoke Application没有执行?

Kor*_*gay 1 ajax jsf jsf-2

我有这个简单的facelets页面:

<!DOCTYPE html>
<html xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
    <title>Index</title>
</h:head>
<h:body>
    <h:form>
        <h:inputText id="firstname" value="#{fooBar.firstname}">
            <f:ajax event="keyup" render="echo" execute="myCommandButton"/>
        </h:inputText>
        <h:commandButton value="Submit" action="#{fooBar.fooBarAction()}" id="myCommandButton"/>
    </h:form>
    <br/>
    <h:outputText id="echo" value="#{fooBar.firstname}"/>
</h:body>
</html>
Run Code Online (Sandbox Code Playgroud)

和Foobar豆如下:

@ManagedBean
@ApplicationScoped
public class FooBar {

    private String firstname;

    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }

    public String getFirstname() {
        return firstname;
    }

    public void fooBarAction() {
        System.out.println("Foo bar action being executed!!!");
    }
}
Run Code Online (Sandbox Code Playgroud)

所以我期望看到每当我在inputText字段中输入内容时都会执行文本Foo bar操作,但实际情况并非如此.我错过了什么?

编辑:为什么我期待这种行为? 我正在研究Core JavaServer Faces一书,在书中注意到:

JSF 2.0将JSF生命周期分为两部分:执行和呈现.

执行包括:还原视图 - >应用请求值 - >进程验证 - >更新模型值 - >调用应用程序

当JSF在服务器上执行组件时,它:

- 转换并验证组件的值(如果组件是输入).

- 将有效输入值推送到模型(如果组件连接到bean属性).

-Executes动作和动作侦听器(如果组件是动作).

所以在这里,myCommandButton应该被执行,不是吗?并且组件的执行意味着它要执行的操作?

编辑#2

此引用来自JavaServer Faces Complete Reference

如果未指定侦听器,则在Invoke Application阶段期间将调用的唯一操作将是与execute属性中列出的ActionSource组件对应的操作.

所以据我所知,在我的例子中,我有一个实现ActionSource接口(myCommandButton)的组件,并且应该执行该组件的action属性.但事实并非如此?

Bal*_*usC 5

该execute属性<f:ajax>基本上告诉JSF在回发期间通过JSF生命周期处理哪些组件.即它基本上告诉JSF它必须执行哪些组件应用请求值,进程验证,更新模型值和调用应用程序阶段.应用请求值阶段将收集(解码)提交的HTML表单(输入和按钮)值.验证阶段将对提交的值运行转换/验证.更新模型值阶段将在backing bean中设置提交/转换/验证的值.调用应用程序阶段将执行提交的操作.请注意,关键是JSF将根据提交的 HTML表单值执行此操作.

换句话说,该execute属性完全是服务器端.正如您所期待的那样,它不是客户端.您似乎希望它告诉webbrowser提交指定的组件,就像您单击它一样.这不是真的.按钮值仅在实际按下/单击/提交时通过JSF生命周期进行处理.

如果在execute属性中指定了按钮,并且JSF在处理生命周期期间确定按钮值实际上未提交(即,在HTTP请求参数映射中完全没有),则JSF将不会在应用请求值阶段期间对动作事件进行排队.所有.因此,在调用应用程序阶段期间不会调用任何内容.

当<f:ajax>事件被触发时,它实际上是作为动作源的封闭组件.因此,您应该在其上挂钩所需的动作侦听器.你可以使用listener属性<f:ajax>.

<h:form>
    <h:inputText id="firstname" value="#{fooBar.firstname}">
        <f:ajax event="keyup" listener="#{fooBar.keyupListener}" render="echo" />
    </h:inputText>
    <h:commandButton value="Submit" action="#{fooBar.fooBarAction}" id="myCommandButton"/>
</h:form>
Run Code Online (Sandbox Code Playgroud)

@ManagedBean
@RequestScoped
public class FooBar {

    private String firstname;

    public void keyupListener() {
        System.out.println("Keyup listener being executed");
    }

    public void fooBarAction() {
        System.out.println("Foo bar action being executed");
    }

    // ...
}
Run Code Online (Sandbox Code Playgroud)

也可以看看: