【问题标题】:JSF CompositeComponent: Implement selectionJSF CompositeComponent:实现选择
【发布时间】:2013-01-11 01:36:03
【问题描述】:

您好,我想实现一个类似的 CC,它实现了一个 selection 属性。这类似于 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>

backing 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 的值表达式一起使用(例如,selection="#{testBean.user}"veSelectionnull(并且 selection 不会打印在调试迭代),我得到一个 NPE。如果我传递一个字符串(例如selection="test",属性 selection 在调试迭代中可用,但是(当然)我得到一个ClassCastException

java.lang.String cannot be cast to javax.el.ValueExpression

如何为我的组件提供 actionListenerselection 属性,并在第一步中设置选定的值,然后调用 actionListener em>?

【问题讨论】:

    标签: java jsf-2 composite-component


    【解决方案1】:

    至于调试迭代,您不会在键集中看到值表达式,也不会在 UIComponent#getAttributes() 的条目集中看到值表达式。 javadoc 中也明确提到了这一点。换句话说,该映射仅包含具有静态值的条目。只有当你在地图上显式调用get(),并且底层属性是一个值表达式时,它才会真正调用它并返回计算值。

    为了获取值表达式,请改用UIComponent#getValueExpression()

    ValueExpression selection = getValueExpression("selection");
    

    至于方法表达式,如果您的组合从UICommand 扩展,那是最简单的,但在您的特定情况下,这很笨拙。只需将侦听器方法的目标设置为命令链接并使用&lt;f:setPropertyActionListener&gt; 在 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>
    

    【讨论】:

      猜你喜欢
      • 2013-06-11
      • 2012-05-18
      • 1970-01-01
      • 2017-06-11
      • 2013-06-28
      • 2017-09-14
      • 2016-05-28
      • 1970-01-01
      相关资源
      最近更新 更多