复合组件的actionListener问题 [英] Problems with actionListener of composite component
问题描述
我要解释在模板中使用一个复合组件时遇到的问题.
I am goin to explain a problem that I have when I use one composite component inside a template.
想象一个这样的视图,它与具有视图范围的通用托管Bean一起使用.我将它作为参数传递给模板.
Imagine one view like this, that work with a generic managed bean with view scope. I pass it to the template as a parameter.
<?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>
模板是这样的.除了其他组件之外,它还使用一个复合组件.
The template is like this. Beside other components, it also use one composite component.
<?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>
如您所见,该模板使用了一个复合组件,这些组件允许指定侦听此事件的动作侦听器.
As you can see, this template use one composite components that allow specify the action listener that hear this event.
<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 ,则不起作用.
If I click in otherButton, it work fine, but if I click in buttonToolbar it don't work.
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表达式.
It seem that it can't resolve the EL expression inside the composite component.
怎么了?如何在一个模板中使用一个复合组件?
What is wrong? How can I use one composite componente inside one template?
我正在使用Mojarra 2.1.7
I am using Mojarra 2.1.7
谢谢.
推荐答案
对不起,我在第一次阅读时就错过了它:
Sorry I missed this on the first read:
您的实现未正确定位属性.我犯了这个错误(因为我敢肯定我们所有人都会这样做).您需要将属性引用为-> #{cc.attrs.someAttribute}
,而不要通过名称来引用.您需要对大多数元素执行此操作,但不能对actionListener
执行此操作.如果那是您的代码,则应该对其进行修复.您的签名是正确的.您正在尝试使用我不熟悉的targetAttributeName
.我的猜测是您需要将组件的id
设置为该名称(因此您的按钮将是myAction
而不是actionListener
(如果我引用的是同一示例).
Your implementation isn't targeting the attributes properly. I made this mistake (as I'm pretty sure all of us do). You need to reference the attributes as -> #{cc.attrs.someAttribute}
not by their name. You do this for most of the elements, but not the actionListener
. If that is your code it should fix it. Your signatures are correct. You're trying to use the targetAttributeName
which I'm not familiar with. My guess is you need to set the id
of the component to that name (so your button would be myAction
not actionListener
(if I'm referencing the same example you are).
此外,我会怎么做:
<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>
我喜欢这种方法,因为它与标记页面的其余方式相似,而且看起来很简单.试一试.
I like this method because it is similar to the rest of the way pages are marked up and it seems simple. Give it a shot.
这篇关于复合组件的actionListener问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!