【问题标题】:Problems with actionListener of composite component复合组件的actionListener问题
【发布时间】:2012-10-30 02:47:01
【问题描述】:

我将解释我在模板中使用一个复合组件时遇到的一个问题。

想象一个像这样的视图,它与具有视图范围的通用托管 bean 一起工作。我将它作为参数传递给模板。

<?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://java.sun.com/jsf/html"  
  xmlns:f="http://java.sun.com/jsf/core"
  xmlns:ui="http://java.sun.com/jsf/facelets"
  xmlns:c="http://java.sun.com/jsp/jstl/core"
  xmlns:trkal="http://java.sun.com/jsf/composite/trkalcomponents">

  <ui:composition template="/template.xhtml">
      <ui:param name="maisuBean" value="#{genericBean}" />
  </ui:composition>
</html>

模板是这样的。除了其他组件,它还使用一个复合组件。

<?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://java.sun.com/jsf/html"  
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:c="http://java.sun.com/jsp/jstl/core"
    xmlns:trkal="http://java.sun.com/jsf/composite/trkalcomponents">

<h:head>
    <title>Titulo</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</h:head>

<h:body>
    <h:form enctype="multipart/form-data">
        ...
        <trkal:toolbarbuttonwidget id="buttonToolbar" label="Action" iconName="toolbar.png"
            buttonAction="#{maisuBean.myActionListener}"
            >
        </trkal:toolbarbuttonwidget>
        ...
        <h:commandLink id="otherButton" actionListener="#{maisuBean.myActionListener}">
            <h:graphicImage library="images" name="toolbar.png" />
            <h:outputText value="Other Action" />
        </h:commandLink>
        ...

    </h:form>
</h:body>
</html> 

如您所见,此模板使用一个复合组件,允许指定听到此事件的动作侦听器。

<composite:interface>
    <composite:attribute name="id" />
    <composite:attribute name="buttonAction" method-signature="void myAction(javax.faces.event.ActionEvent)" targetAttributeName="actionListener"/>
    <composite:attribute name="iconName" />
    <composite:attribute name="label"/>
    <composite:attribute name="title"/>
    <composite:attribute name="styleClass"/>
</composite:interface>
<composite:implementation>
    <h:outputStylesheet target="head" library="trkalcomponents" name="toolbarbuttonwidget.css"  />
    <h:commandLink id="buttonAction">
        <h:graphicImage library="images" name="#{cc.attrs.iconName}" />
        <h:outputText value="#{cc.attrs.label}" />
    </h:commandLink>
</composite:implementation>

如果我点击otherButton,它可以正常工作,但如果我点击buttonToolbar,它就不起作用。

09-nov-2012 19:16:28 javax.faces.event.MethodExpressionActionListener processAction
GRAVE: Se ha recibido 'javax.el.PropertyNotFoundException' al invocar la escucha de acción '#{maisuBean.myActionListener}' para el componente 'buttonAction'
09-nov-2012 19:16:28 javax.faces.event.MethodExpressionActionListener processAction
GRAVE: javax.el.PropertyNotFoundException: /template.xhtml @20,6 buttonAction="#{maisuBean.myActionListener}": Propiedad 'myActionListener' no hallada en el tipo com.joxeja.test.ToolBarBean
    at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:111)

似乎无法解析复合组件内部的EL表达式。

怎么了?如何在一个模板中使用一个复合组件?

我正在使用 Mojarra 2.1.7

谢谢。

【问题讨论】:

  • #{maisuBean.myActionListener}'
  • 是的,bean 已注册,正如我所说,如果我单击 otherButton commandLink,它就可以工作。 bean 注册为 @ManagedBean(name="genericBean") 和 @ViewScoped。

标签: jsf jsf-2 composite-component


【解决方案1】:

对不起,我在第一次阅读时错过了这个:

您的实现未正确定位属性。我犯了这个错误(我很确定我们所有人都这样做)。您需要将属性引用为 -> #{cc.attrs.someAttribute} 而不是其名称。您对大多数元素执行此操作,但不是 actionListener。如果那是您的代码,它应该修复它。你的签名是正确的。您正在尝试使用我不熟悉的targetAttributeName。我的猜测是您需要将组件的 id 设置为该名称(因此您的按钮将是 myAction 而不是 actionListener(如果我引用的示例与您相同)。

除此之外,我会怎么做:

    <composite:interface>
    <composite:attribute name="id" />
    <!-- 
    <composite:attribute name="buttonAction" method-signature="void myAction(javax.faces.event.ActionEvent)" targetAttributeName="actionListener"/>
    -->
    <composite:attribute name="buttonAction" method-signature="void action(javax.faces.event.ActionEvent)"/>  
    <composite:attribute name="iconName" />
    <composite:attribute name="label"/>
    <composite:attribute name="title"/>
    <composite:attribute name="styleClass"/>
</composite:interface>
<composite:implementation>
    <h:outputStylesheet target="head" library="trkalcomponents" name="toolbarbuttonwidget.css"  />
        <!-- fix below -->
        <h:commandLink id="buttonAction" actionListener=#{cc.attrs.buttonAction}>
            <h:graphicImage library="images" name="#{cc.attrs.iconName}" />
            <h:outputText value="#{cc.attrs.label}" />
        </h:commandLink>
    </composite:implementation>

我喜欢这种方法,因为它类似于页面标记的其余方式,而且看起来很简单。试一试。

【讨论】:

  • 非常感谢您的帮助,但我尝试过这种方式,结果是一样的。错误消息是它找不到托管 bean genericBean 的属性 myActionListener。就像它尝试为此属性调用 getter 方法一样,从逻辑上讲它不存在。
  • 确认:如果你这样做了 -> &lt;h:commandButton actionListener="#{genericBean.myActionListener}" /&gt; 以它工作的形式?您的错误听起来根本不起作用,而不是它在组件内部不起作用。
  • 是的,模板的commandLink otherButton 工作正常,但是teamplate 的toolbarbuttonwidget buttonToolbar 不起作用。一个大细节。我不能放 genericBean.myActionListener 因为模板管理 bean maisuBean。模板接收 bean 的引用作为参数。有一些层次:使用页面、模板和复合组件,每个都管理它的bean,接收或传递参数。在每个级别中,我都可以使用它的参考。复合组件中给出的问题,无法解析监听器方法的EL表达式。
猜你喜欢
  • 1970-01-01
  • 2023-04-01
  • 2013-10-22
  • 2012-04-12
  • 1970-01-01
  • 2013-02-10
  • 2011-10-10
  • 2013-04-21
  • 1970-01-01
相关资源
最近更新 更多