0

版本: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 中使用它的方式

输入.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 中获得结果。

然后我看到这篇文章 将参数传递给复合组件动作属性

所以我将实际的 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:在 java.lang.String 类型上找不到属性“selectedInfoRecord”

然后我尝试将 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

4

1 回答 1

2

我已经检查了问题,寻找可能的错误,但没有错误。相反,它与了解 f:setPropertyActionListener 如何工作有关。

此标记将从 EL 表达式中检索到的值设置为“目标”属性所指向的属性。如果您尝试使用“目标”属性调用方法,它将不起作用,因为它不是这样设计的。

正确的做法是这样:

<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 的引用,这样才能正确解决链。

于 2016-02-27T04:27:32.240 回答