<ui:include> 中的参数化方法调用,方法参数数量可变
Parameterized method call in <ui:include> with variable number of method parameters
我有一个模板,它是用于编辑某些元素的表单的一部分。要执行的操作因包含它的页面而异。所以我将动作方法作为参数传递:
<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),但我不确定这是否可行。
有什么办法可以实现吗?
最后我解决了这个问题,在控制器中创建了一个 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);
}
我有一个模板,它是用于编辑某些元素的表单的一部分。要执行的操作因包含它的页面而异。所以我将动作方法作为参数传递:
<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),但我不确定这是否可行。
有什么办法可以实现吗?
最后我解决了这个问题,在控制器中创建了一个 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);
}