我们有一个要求,允许用户配置所有数据表中列的顺序,包括上面有操作按钮的列,这里p:commandButton
是 s。
因此,我们对必须手动实例化的所有列使用绑定。对于仅显示一些字符串、布尔值、日期和数字的所有列都可以正常工作,但是当将p:commandButton
s 添加到具有一个或多个<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:配置是 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 并在 value 上调用 setter,所以我假设ValueExpression
s 就足够了。
更新 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。记得setId()
在实例化 PrimeFaces 时调用CommandButton
。