【问题标题】:Cannot invoke listener method from f:ajax inside composite component无法从复合组件内的 f:ajax 调用侦听器方法
【发布时间】:2015-02-25 14:35:52
【问题描述】:

这是我的复合组件hc:rangeChooser

<ui:component xmlns="http://www.w3.org/1999/xhtml"
              xmlns:f="http://java.sun.com/jsf/core"
              xmlns:h="http://java.sun.com/jsf/html"
              xmlns:ui="http://java.sun.com/jsf/facelets"
              xmlns:cc="http://java.sun.com/jsf/composite"
              xmlns:p="http://primefaces.org/ui">
    <cc:interface componentType="rangeChooser">
        <cc:clientBehavior name="rangeSelected" event="change" targets="#{cc.clientId}:datetype"/>
    </cc:interface>

    <cc:implementation>

        <div id="#{cc.clientId}">
            <h:outputScript library="primefaces" name="jquery/jquery.js" target="head" />
            <h:outputScript library="primefaces" name="jquery/jquery-plugins.js" target="head" />
            <h:outputScript library="javascript" name="rangeChooser.js" />
            <h:outputStylesheet library="primefaces" name="primefaces.css" target="head" />
            <h:outputStylesheet library="primefaces" name="jquery/ui/jquery-ui.css" target="head"/>

            <script type="text/javascript">
                var variables = {};
                variables.formid = '#{cc.clientId}';
            </script>

            <h:selectOneMenu id="datetype" value="#{cc.attrs.selectedRange}" onchange="dateFunc();">
                <f:selectItems value="#{cc.attrs.ranges}"></f:selectItems>
            </h:selectOneMenu>

            ....

            <p:inputText id="hiddenValue" value="#{cc.attrs.range}"/>
        </div>
    </cc:implementation>
</ui:component>

当我在&lt;h:selectOneMenu&gt; 中选择某些内容时,我会运行dateFunc();,它将从中选择的值传递给&lt;h:inputText&gt;,以后它将被隐藏。

现在,这是我使用此组件的一种方式:

<h:form id="form">
    <p:growl id="growl"></p:growl>
    <hc:rangeChooser1>
        <f:ajax event="rangeSelected"
                onevent="alert('It works');"
                listener="#{testBean.update}" 
                update=":form:growl"/>
    </hc:rangeChooser1>
</h:form>

最后是我的 backing bean 的方法:

public void update(AjaxBehaviorEvent e){
    SimpleDateFormat df = new SimpleDateFormat("dd MMM yyyy");
    text = df.format(from.getTime()) + " " + df.format(to.getTime());
     FacesContext context = FacesContext.getCurrentInstance();

     context.addMessage(null, new FacesMessage("Successful" + text,  "Your message: " + text) );
     context.addMessage(null, new FacesMessage("Second Message", "Additional Message Detail"));
}

当我更改选择时,一切正常,除了 &lt;f:ajax&gt; 不调用 testBean 的更新 method,但它调用函数 alert('it works');

当我使用&lt;p:remoteCommand&gt; 时,我可以从&lt;f:ajax onevent="myRemote"&gt; 调用然后定义

<p:remoteCommand name="myRemote" actionListener="#{testBean.update}" 
                 update="growl"/>

但我不喜欢这个解决方案,也不明白为什么我的方法不起作用。

【问题讨论】:

    标签: jsf jsf-2 composite-component


    【解决方案1】:

    首先,

    <cc:clientBehavior ... targets="#{cc.clientId}:datetype" />
    

    targets 属性的值错误。它是相对于&lt;cc:implementation&gt; 进行解释的,但是#{cc.clientId} 错误地期望它相对于其NamingContainer 父级进行解释。去掉 #{cc.clientId}: 前缀。

    <cc:clientBehavior ... targets="datetype" />
    

    不要忘记通知作者您发现此错误信息的来源。这不是我第一次看到初学者使用这个,所以互联网上肯定有一些来源在传播这种错误信息,应该被告知。

    其次,

    <f:ajax ... update=":form:growl" />
    

    &lt;f:ajax&gt; 不支持 update 属性。这是 PrimeFaces 特有的。您可能打算使用render

    <f:ajax ... render=":form:growl" />
    

    与具体问题无关&lt;f:ajax onevent="alert('It works');"&gt; 无法正常工作,因为不支持此构造。 onevent 属性的值应该代表函数引用的名称,而不是函数调用。因此,要么这是一种错误的观察,要么是您在没有实际测试的情况下过度简化/假设了太多。

    【讨论】:

    • 非常感谢@BalusC,本文给出了这个例子:ibm.com/developerworks/java/library/j-jsf2fu-0610/index.html
    • 哦。那是一篇很老的文章了。它可能依赖于史前错误。这至少不是正确的方法。我给作者留个邮件,谢谢。
    • 再次感谢它有效,并借此机会感谢您在这里提供宝贵的文章和答案。
    猜你喜欢
    • 2012-04-08
    • 1970-01-01
    • 1970-01-01
    • 2014-03-13
    • 2013-12-14
    • 2020-06-13
    • 2017-09-14
    • 2012-08-11
    • 1970-01-01
    相关资源
    最近更新 更多