复合组件的actionListener问题

时间:2012-11-09 18:30:06

标签: jsf jsf-2 composite-component

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

想象一下这样的一个视图,它与带有视图范围的通用托管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

感谢。

1 个答案:

答案 0 :(得分:1)

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

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

除此之外,我将如何做到:

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

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