我们要求允许用户在所有数据表中配置列的顺序,包括在其上有操作按钮的列,此处为p:commandButton
s。
因此我们对所有列都使用绑定,我们必须手动实例化。对于仅显示某些字符串,布尔值,日期和数字的所有列都可以正常工作,但是在将p:commandButton
添加到其上有一个或多个<f:setPropertyActionListener>
s的列时会出现问题。
ELContext elContext = FacesContext.getCurrentInstance().getELContext();
ExpressionFactory factory = FacesContext.getCurrentInstance().getApplication().getExpressionFactory();
CommandButton button = new CommandButton();
button.setIcon( "ui-icon ui-icon-pencil" );
button.setProcess( "@this" );
button.setUpdate( ":compliance-case-dialog :compliance-case-form:data" );
button.setOncomplete( "complianceCaseDialog.show();" );
ValueExpression targetExpression = factory.createValueExpression( elContext, "#{complianceCaseManager.selectedComplianceCaseWithRefresh}", ComplianceCase.class );
ValueExpression valueExpression = factory.createValueExpression( elContext, "#{coca}", ComplianceCase.class );
button.addActionListener( new SetPropertyActionListenerImpl( targetExpression, valueExpression ) );
column.getChildren().add( button ); // add to Column instance
此按钮“正确”显示<p:dialog>
,但在显示之前,应使用数据表的当前实体(由ComplianceCaseManager
定义)调用setSelectedComplianceCaseWithRefresh( ComplianceCase selectedComplianceCase )
类'var="coca"
方法对话框。
<p:dataTable id="data"
widgetVar="resultTable"
value="#{complianceCaseManager.complianceCases}"
var="coca"
...>
</p:dataTable>
调试显示永远不会调用setSelectedComplianceCaseWithRefresh( ComplianceCase selectedComplianceCase )
方法。
问:
怎么了?你是如何解决这个问题的?
PS:config是PrimeFaces 3.4.2,Mojarra 2.1.22,GlassFish 3.1.2.2,Java 7
更新1:
这是我要翻译成程序化的p:commandButton:
<p:commandButton icon="ui-icon ui-icon-pencil"
title="#{msg['complianceCaseManager.data.edit.button.hint']}"
process="@this"
update=":compliance-case-dialog :compliance-case-form:data"
oncomplete="complianceCaseDialog.show();">
<p:resetInput target=":unlocked-form" />
<f:setPropertyActionListener target="#{complianceCaseManager.selectedComplianceCaseWithRefresh}" value="#{coca}" />
<f:setPropertyActionListener target="#{complianceCaseManager.mode}" value="EDIT" />
</p:commandButton>
该行
<f:setPropertyActionListener target="#{complianceCaseManager.selectedComplianceCaseWithRefresh}" value="#{coca}" />
是我必须上班的人。
kolossus创建MethodExpressionActionListener
的解决方案对我的代码不起作用:
String targetExpressionString = "#{complianceCaseManager.selectedComplianceCaseWithRefresh}";
String valueExpressionString = "#{coca}";
MethodExpression targetMethodExpression = factory.createMethodExpression( elContext, targetExpressionString, null, new Class<?>[]{ ComplianceCase.class } );
MethodExpression valueMethodExpression = factory.createMethodExpression( elContext, valueExpressionString, ComplianceCase.class, new Class<?>[0] );
button.addActionListener( new MethodExpressionActionListener( targetMethodExpression, valueMethodExpression ) );
制作AFAIK,以便在目标上调用setter,并在调用setter的值上,所以我假设ValueExpression
足够了。
更新2:
尝试通过EL 2.2方法调用设置当前实体也不起作用。
代码:
String methodExpressionString = "#" + "{complianceCaseManager.selectedComplianceCaseWithRefresh(coca)}";
MethodExpression methodExpression = factory.createMethodExpression( elContext, methodExpressionString, null, new Class<?>[]{ ComplianceCase.class } );
button.addActionListener( new MethodExpressionActionListener( methodExpression ) );
什么都没有。
更新3:
这是正确的<:setPropertyActionListener>
代码:
// traditional <f:setPropertyActionListener target="#{complianceCaseManager.selectedComplianceCaseWithRefresh}" value="#{coca}" />
ValueExpression targetExpression = factory.createValueExpression( elContext, "#{complianceCaseManager.selectedComplianceCaseWithRefresh}", ComplianceCase.class );
ValueExpression valueExpression = factory.createValueExpression( elContext, "#{coca}", ComplianceCase.class );
button.addActionListener( new SetPropertyActionListenerImpl( targetExpression, valueExpression ) );
非常感谢kolossus。在实例化PrimeFaces setId()
时,请务必致电CommandButton
。
答案 0 :(得分:1)
应将actionListener创建为MethodExpression
而不是ValueExpression
:
我假设factory instanceOf ExpressionFactory
。使用createMethodExpression factory
MethodExpression targetExpression = factory.createMethodExpression( elContext, "#{complianceCaseManager.selectedComplianceCaseWithRefresh(coca)}",null,new Class[]{ComplianceCase.class} );
将侦听器添加到组件:
button.addActionListener( new MethodExpressionActionListener(targetExpression));
与当前问题不完全相关,您还省略了组件的id
属性。为安全起见,请添加
button.setId("theButton");
编辑:您必须在动态创建命令组件时设置id
属性
答案 1 :(得分:0)
我曾经使用lambda表达式来解决它:
private final ActionListener actionListener = (ActionEvent event) -> {
//code to execute
};
然后只是:
comandButton.setId(id);
commandButon.addActionListener(actionListener);