2015-02-09 2 views
3

У меня есть шаблон, который является частью формы для редактирования некоторого элемента. Выполняемое действие отличается в зависимости от страницы, в которую оно включено. Поэтому я передаю метод действия в качестве параметра:Параметрированный вызов метода в <ui:include> с переменным числом параметров метода

<ui:param name="option" value="#{someOptionBean}" /> 
... 
<ui:include src="/WEB-INF/jsf/value-edit.xhtml"> 
    <ui:param name="controllerParam" value="#{optionController}" /> 
    <ui:param name="elementParam" value="#{option}" /> 
    <ui:param name="actionParam" value="updateOption" /> 
</ui:include> 

или:

<ui:param name="property" value="#{somePropertyBean}" /> 
... 
<ui:include src="/WEB-INF/jsf/value-edit.xhtml"> 
    <ui:param name="controllerParam" value="#{propertyController}" /> 
    <ui:param name="elementParam" value="#{property}" /> 
    <ui:param name="actionParam" value="updateProperty" /> 
</ui:include> 

и value-edit.xhtml есть кнопка команды:

<p:commandButton value="Update" action="#{controllerParam[actionParam](elementParam)}" /> 

До сих пор все работает отлично.

Моя проблема заключается в том, что теперь методы действия не имеют одинакового количества параметров. К ним относятся:

public void updateOption(Option option) { ... } 
public void updateProperty(Item item, Prop property) { ... } 

так теперь я хочу, чтобы иметь возможность также определить параметры действия, чтобы иметь что-то вроде:

<ui:param name="actionParam" value="updateOption(option)" /> 
<ui:param name="actionParam" value="updateProperty(item, property)" /> 

или что-то вроде:

<ui:param name="method" value="updateProperty" /> 
<ui:param name="parameters" value="item, property" /> 

Я прочитал документы (Value and Method Expressions/Parameterized Method Calls), и я не уверен, что это возможно.

Есть ли способ достичь этого?

ответ

3

Наконец я решил эту создавая MethodExpression в контроллере

Теперь ui:include выглядит как:

<ui:param name="option" value="#{someOptionBean}" /> 
... 
<ui:include src="/WEB-INF/jsf/value-edit.xhtml"> 
    <ui:param name="actionParam" value="#{optionController.getUpdateAction()}" /> 
</ui:include> 

и

<ui:param name="item" value="#{someItemBean}" /> 
<ui:param name="property" value="#{somePropertyBean}" /> 
... 
<ui:include src="/WEB-INF/jsf/value-edit.xhtml"> 
    <ui:param name="actionParam" value="#{propertyController.getUpdateAction()}" /> 
</ui:include> 

В value-edit.xhtml кнопку команда:

<p:commandButton value="Update" action="#{actionParam}" /> 

getUpdateAction создает MethodExpression с соответствующими параметрами для каждого контроллера:

public class OptionController { 
    ... 
    public void updateOption(Option option) { ... } 

    public MethodExpression getUpdateAction() { 
     return createMethodExpression("#{optionController.updateOption(option)}", String.class, Option.class); 
    } 
    ... 
} 

public class PropertyController { 
    ... 
    public void updateProperty(Item item, Prop property) { ... } 

    public MethodExpression getUpdateAction() { 
     return createMethodExpression("#{propertyController.updateProperty(item, property)}", String.class, Item.class, Prop.class); 
    } 
    ... 
} 

, где createMethodExpression является:

public static MethodExpression createMethodExpression(String expression, Class<?> expectedReturnType, Class<?>... expectedParameterTypes) { 
    FacesContext facesContext = FacesContext.getCurrentInstance(); 
    return facesContext.getApplication().getExpressionFactory().createMethodExpression(
     facesContext.getELContext(), expression, expectedReturnType, expectedParameterTypes); 
}