2012-05-22 95 views
4

我想要實現這個使用動態參數值表達式:嵌套JSF表達串

<h:dataTable value="#{someBean.someValue}" var="field"> 
    <h:column>#{anotherBean[field]}</h:column> 
</h:dataTable> 

其中field'user.name''location.address.zip'或...

這可能嗎?

請注意,這是一個簡單的例子,我對ValueExpression不在dataTable組件感興趣。

UPDATE 現在的問題是:如何替換標準BeanELResolver?

在尋找ELUtils:

... 
    composite.addRootELResolver(IMPLICIT_RESOLVER); 
    composite.add(FLASH_RESOLVER); 
    composite.addPropertyELResolver(COMPOSITE_COMPONENT_ATTRIBUTES_EL_RESOLVER); 
    addELResolvers(composite, associate.getELResolversFromFacesConfig()); 
    addVariableResolvers(composite, FacesCompositeELResolver.ELResolverChainType.Faces, 
      associate); 
    addPropertyResolvers(composite, associate); 
    composite.add(associate.getApplicationELResolvers()); 
    composite.addRootELResolver(MANAGED_BEAN_RESOLVER); 
    composite.addPropertyELResolver(RESOURCE_RESOLVER); 
    composite.addPropertyELResolver(BUNDLE_RESOLVER); 
    ... 

,但我不完全理解解析器鏈尚未...所以我會去研究:)

更新2

驗證碼作品;)

public class ExtendedBeanELResolver extends BeanELResolver 
{ 
    @Override 
    public Object getValue(ELContext context, Object base, Object property) throws NullPointerException, PropertyNotFoundException, ELException 
    { 
     try 
     { 
      return super.getValue(context, base, property); 
     } 
     catch(PropertyNotFoundException e) 
     { 
      try 
      { 
       Object value = base; 

       for(String part : property.toString().split("\\.")) 
       { 
        value = super.getValue(context, value, part); 
       } 

       return value; 
      } 
      catch(PropertyNotFoundException e1) 
      { 
       context.setPropertyResolved(false); 
      } 
     } 

     return null; 
    } 
} 
+0

不,我說的是正確的:'公開名單 getSomeValue(){...}' –

回答

9

這是默認不支持特德。您需要在這裏定製ELResolver。最簡單的就是擴展現有的BeanELResolver

這裏有一個開球例如:

public class ExtendedBeanELResolver extends BeanELResolver { 

    @Override 
    public Object getValue(ELContext context, Object base, Object property) 
     throws NullPointerException, PropertyNotFoundException, ELException 
    { 
     if (property == null || base == null || base instanceof ResourceBundle || base instanceof Map || base instanceof Collection) { 
      return null; 
     } 

     String propertyString = property.toString(); 

     if (propertyString.contains(".")) { 
      Object value = base; 

      for (String propertyPart : propertyString.split("\\.")) { 
       value = super.getValue(context, value, propertyPart); 
      } 

      return value; 
     } 
     else { 
      return super.getValue(context, base, property); 
     } 
    } 

} 

得到它的運行,如faces-config.xml如下注冊它:

<application> 
    <el-resolver>com.example.ExtendedBeanELResolver</el-resolver> 
</application> 
+0

這正是我正在尋找解決這個和其他一些小事情。感謝@BalusC,你爲我節省了很多時間,因此你應該得到我工資的一部分;) –

+0

然而,在'faces-config.xml'中聲明它將覆蓋默認的'CompositeELResolver'。如何在'CompositeELResolver.elResolvers'中替換標準'BeanELResolver'? –

+0

哎呀,我錯了。它不覆蓋,但之前插入。查看問題更新。 –

2

關於這一主題所作的工作很有趣,但不完整。

如果您在組件中設置的複合組件中傳遞值,則該組件不起作用。

實施例:

<composite:interface> 
    <composite:attribute name="value" type="java.lang.Boolean" required="true" /> 
</composite:interface> 
<composite:implementation> 
     <h:inputText id="inputValue" value="#{cc.attrs.value}" 
     </h:inputText> 
</composite:implementation> 

隨着ExtendedBeanElResolver,它將引發PropertyNotFoundException當我設置值。

所以,我花了幾個小時找到一個解決方案,而這裏是工作的解決方案,以便能夠使用ExtendedBeanElResolver與設置複合材料部件內值的能力:

public class ExtendedBeanELResolver extends BeanELResolver { 

    private static final String PRIMEFACES_RESOURCE_PREFIX = "primefaces:"; 
    private static final String RESOURCES_HANDLER = "class org.omnifaces.resourcehandler.GraphicResourceHandler"; 
    private static final String PRIMEFACES_EXT_RESOURCES_HANDLER = "class org.primefaces.extensions.application.PrimeFacesExtensionsResourceHandler"; 

    @Override 
    public Object getValue(ELContext context, Object base, Object property) { 

      if (property == null || base == null || base instanceof ResourceBundle || base instanceof Map || base instanceof Collection 
        || property.toString().startsWith(PRIMEFACES_RESOURCE_PREFIX) || base.getClass().toString().equals(RESOURCES_HANDLER) 
        || base.getClass().toString().equals(PRIMEFACES_EXT_RESOURCES_HANDLER)) { 
       return null; 
      } 
      String propertyString = property.toString(); 
      if (propertyString.contains(".")) { 
       Object value = base; 

       for (String propertyPart : propertyString.split("\\.")) { 
        value = super.getValue(context, value, propertyPart); 
       } 

       return value; 
      } else { 
       Object v = super.getValue(context, base, property); 
       return v; 
      } 
    } 

    @Override 
    public void setValue(ELContext context, Object base, Object property, Object val) { 
     if (base != null && !(base instanceof ResourceBundle) && !(base instanceof Map) && !(base instanceof Collection)) 
      super.setValue(context, base, property, val); 
    } 
} 

(我加的「setValue」部分)。

現在它的工作。不要猶豫,給我您的反饋,因爲這是我在這個網站上的第一篇文章!