Передача имен методов действий в качестве аргументов в facelets componenets

#jsf #facelets #myfaces

#jsf #facelets #myfaces

Вопрос:

Я вызываю шаблон и передаю параметры, подобные приведенным ниже:

 <ui:include src="WEB-INF/Subviews/ProductEdit.xhtml">
    <ui:param name="items" value="#{produtList}"></ui:param>
    <ui:param name="itemToEdit" value="#{productToEdit}"></ui:param>
</ui:include>
  

и в ProductEdit.xhtml у меня есть что-то вроде

 <ui:repeat value="#{items}" var="item">
  <tr>
    ...
    ...
    <td style="text-align: center">
      <h:commandLink style="cssGenericColumn" action="#{productEditAction}">
         <f:setPropertyActionListener target="#{itemToEdit}" value="#{item}"/>
      </h:commandLink>    
    </td>
  <tr>
</ui:repeat>
  

который работает нормально.

Теперь я хочу параметризовать #{productEditAction} в ProductEdit.xhtml и поэтому я сделал следующее

 <ui:include src="WEB-INF/Subviews/ProductEdit.xhtml">
    <ui:param name="items" value="#{produtList}"></ui:param>
    <ui:param name="itemToEdit" value="#{productToEdit}"></ui:param>
    <ui:param name="itemEditAction" value="#{productEditAction}"></ui:param>
</ui:include>
  

на первой странице, а затем в ProductEdit.xhtml я делаю

 <ui:repeat value="#{items}" var="item">
  <tr>
    ...
    ...
    <td style="text-align: center">
      <h:commandLink style="cssGenericColumn" action="#{itemEditAction}">
         <f:setPropertyActionListener target="#{itemToEdit}" value="#{item}"/>
      </h:commandLink>    
    </td>
  <tr>
</ui:repeat>
  

и это приводит к следующей ошибке

 javax.faces.el.EvaluationException: /WEB-INF/Subviews/ProductEdit.xhtml @45,89 action="#{itemEditAction}": Identity 'itemEditAction' does not reference a MethodExpression instance, returned type: java.lang.String
at com.sun.facelets.el.LegacyMethodBinding.invoke(LegacyMethodBinding.java:    at org.apache.myfaces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:    at javax.faces.component.UICommand.broadcast(UICommand.java:109)....
 ....
 ....
 ....
  

Это, однако, работает, если действие привязано к объекту модели. Итак, что-то вроде

  <h:commandLink style="cssGenericColumn" action="#{item.editAction}">
  

Есть идеи?

Ответ №1:

Передача метода в качестве параметра должна выполняться следующим образом:

 itemBean="#{bean}"
itemEditAction="productEditAction"
  

и в вашем компоненте вы будете объединять их:

 action="#{itemBean[itemEditAction]}"
  

Комментарии:

1. Благословляю вас, сэр! Вы избавили меня от необходимости пробивать кулаком монитор или, что еще хуже, от необходимости переделывать мое приложение.

2. Если в контроллере не было метода с именем «productEditAction», это выдаст ошибку во время выполнения, а не во время компиляции, потому что мы передаем имя метода в виде строки вместо прямой передачи метода (вроде как javascript), верно?

3. Подождите, где происходит это присвоение параметра itemEditAction? Ни ui:param, ни ui:include не имеют таких параметров.

Ответ №2:

Возможно, actionmappert-обработчик действий сработал бы.