版本:MyFaces 2.2.8
问题: 我有一些复合组件,它将为从复合传递的变量赋值。 它适用于Mojara 2.2.12(在迁移到Myfaces 2.2.8之前)。
这是我的复合代码: info.xhtml
<composite:interface>
<composite:attribute name="id" />
<composite:attribute name="methodToGetRecordFromInfo" method-signature="java.util.List action(id.co.sg.core.Dto)" required="true" />
</composite:interface>
<p:dataTable id="tblInfoCodeComponent"
var="codeComponent"
value="#{infoBean.grid}"
<p:columnGroup type="header">
<p:row>
<p:column headerText="CodeComponent"/>
</p:row>
</p:columnGroup>
<p:column>
<p:commandLink value="#{codeComponent.map['componentCode']}"
process="@this"
icon="ui-icon-search"
update="#{infoBean.field.map['update']}">
<f:setPropertyActionListener
value="#{infoBean.wrap(codeComponent)}"
target="#{cc.attrs.methodToGetRecordFromInfo}" />
</p:commandLink>
</p:column>
</p:dataTable>
这是复合bean代码中的方法 infoBean.java
public Dto wrap(Dto codeComponentRecord) {
Dto result = new Dto();
result.putString("callerId", "callerId");
result.putDto("record", codeComponentRecord.clone());
return result;
}
Dto,是我们用来简化作品的某种地图对象。
这就是我们在主xhtml中使用它的方式
input.xhtml
<info:codeComponentInfo id="codeComponentInfo" methodToGetRecordFromInfo="#{inputBean.selectedInfoRecord}" />
这是inputBean.java中的代码
private Dto selectedInfoRecord;
public void setSelectedInfoRecord(Dto infoDto){
String id = infoDto.getString("callerId","");
activeRow.putDto("codeComponent", infoDto.getDto("record"));
}
public Dto getSelectedInfoRecord() {
return selectedInfoRecord;
}
当我使用MyFaces 2.2.8时,setSelectedInfoRecord方法不会调用。 所以,我无法从inputBean中的infoBean中获取结果。
然后我看到了这篇文章 Pass Argument to a composite-component action attribute
所以我将实际的info.xhtml代码修改为这个
<composite:interface>
<composite:attribute name ="beanName" type="java.lang.Object"/>
<composite:attribute name ="methodName" type="java.lang.String"/>
</composite:interface>
...
<f:setPropertyActionListener
value="#{infoBean.wrap(codeComponent)}"
target="#{cc.attrs.beanName[cc.attrs.methodName]}" />
这是新的input.xhtml
<info:goodsCodeComponentInfo id="goodsCodeComponentInfo" beanName="infoBean" methodName="selectedInfoRecord"/>
但这是我发现的
错误BusinessExceptionHandler - $$$$$发生未处理的异常 org.apache.myfaces.view.facelets.el.ContextAwarePropertyNotFoundException:javax.el.PropertyNotFoundException:Property&#39; selectedInfoRecord&#39;在类型java.lang.String
上找不到
然后我尝试将info.xhtml修改为这个
<f:setPropertyActionListener
value="#{infoBean.wrap(codeComponent)}"
target="#{cc.attrs.beanName.methodName}" />
或者这个
<f:setPropertyActionListener
value="#{infoBean.wrap(codeComponent)}"
target="#{cc.attrs.beanName.selectedInfoRecord}" />
仍然有与上面相同的错误..
所以我尝试再次修改它到这个
<f:setPropertyActionListener
value="#{infoBean.wrap(codeComponent)}"
target="#{inputBean.selectedInfoRecord}" />
效果很好!!!但这不是我需要的,我需要从参数传递bean名称。
任何人都可以帮我解决这个问题吗?
我正在使用Java 8和tomcat 8.0.30以及EL 3
答案 0 :(得分:2)
我已经检查了寻找可能的错误的问题,但没有错误。相反,它与理解f:setPropertyActionListener如何工作有关。
此标记将从EL表达式检索的值设置为“target”属性指向的属性。如果您尝试使用“target”属性调用方法,它将无法工作,因为这不是它的设计方式。
这样做的正确方法是:
<info:codeComponentInfo bean="#{inputBean}" methodName="selectedInfoRecord"/>
在复合组件中:
<cc:attribute name ="bean" type="java.lang.Object"/>
<cc:attribute name ="methodName" type="java.lang.String"/>
....
<f:setPropertyActionListener
value="#{infoBean.wrap(codeComponent)}"
target="#{cc.attrs.bean[cc.attrs.methodName]}" />
这里的关键是你需要传递对bean的引用,这样就可以正确地解决链。