您好我想实现类似的CC,它实现选择属性。这类似于Primefaces instant row selection <p:dataTable selection="#{bean.user}" .../>
。
这是复合材料中的相关定义:
<composite:interface componentType="my.CcSelection">
<composite:attribute name="actionListener" required="true"
method-signature="void listener(javax.faces.event.AjaxBehaviorEvent)"/>
<composite:attribute name="selection"/>
</composite:interface>
<composite:implementation>
...
<ui:repeat var="item" value="#{cc.attrs.data}">
<p:commandLink actionListener="#{cc.actionListener(item)}"/>
</ui:repeat>
...
</composite:implementation>
支持bean中的actionListener
- 方法如下:
public void actionListener(MyObject object)
{
logger.info("ActionListener "+object); //Always the correct object
FacesContext context = FacesContext.getCurrentInstance();
Iterator<String> it = this.getAttributes().keySet().iterator();
while(it.hasNext()) { //Only for debugging ...
logger.debug(it.next());
}
// I want the set the value here
ValueExpression veSelection = (ValueExpression)getAttributes().get("selection");
veSelection.setValue(context.getELContext(), object);
// And then call a method in a `@ManagedBean` (this works fine)
MethodExpression al = (MethodExpression) getAttributes().get("actionListener");
al.invoke(context.getELContext(), new Object[] {});
}
如果我使用带有选择的值表达式的CC(例如selection="#{testBean.user}"
,veSelection
为null
(并且选择没有在调试迭代中打印出来,我得到一个NPE。如果我传递一个字符串(例如selection="test"
),属性选择在调试迭代中可用,但是(当然)我得到ClassCastException
:
java.lang.String cannot be cast to javax.el.ValueExpression
如何为组件提供 actionListener 和选择属性,并在第一步中设置所选值,然后调用 actionListener
答案 0 :(得分:2)
对于调试迭代,您不会在UIComponent#getAttributes()
的键集或入口集中看到值表达式。 javadoc中也明确提到了这一点。换句话说,该映射仅包含具有静态值的条目。只有在地图上显式调用get()
并且底层属性是值表达式时,它才会实际调用它并返回评估值。
要获得值表达式,请改用UIComponent#getValueExpression()
。
ValueExpression selection = getValueExpression("selection");
关于方法表达式,嗯,如果你的复合从UICommand
扩展,这是最简单的,但这在你的特殊情况下是简单的笨拙。只需将侦听器方法的目标设置为命令链接,并使用<f:setPropertyActionListener>
在bean中设置所需的属性。这样就不需要支持组件了。
<composite:interface>
<composite:attribute name="actionListener" required="true" targets="link"
method-signature="void listener(javax.faces.event.AjaxBehaviorEvent)"/>
<composite:attribute name="selection"/>
</composite:interface>
<composite:implementation>
...
<ui:repeat var="item" value="#{cc.attrs.data}">
<p:commandLink id="link">
<f:setPropertyActionListener target="#{cc.attrs.selection}" value="#{item}" />
</p:commandLink>
</ui:repeat>
...
</composite:implementation>