4

値式の動的パラメーターを使用してこれを実現したい:

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

どこfieldですか'user.name'、それとも'location.address.zip'...

出来ますか?

これは単純な例であることに注意してください。コンポーネントではValueExpressionないことに興味があります。dataTable

更新 問題は次のとおりです。標準の 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;
    }
}
4

2 に答える 2

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>
于 2012-05-22T04:23:12.313 に答える
4

このトピックに関する作業は非常に興味深いものですが、完全ではありません。

このコンポーネントに設定されている複合コンポーネントに値を渡すと、機能しません。

例 :

<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」部分を追加しました)。

そして今、それは機能します。これはこのウェブサイトでの最初の投稿なので、遠慮なくフィードバックをお寄せください。

于 2016-03-02T16:51:22.420 に答える