Кнопка команды Bootsfaces вызывает исключение «Подвыражение 0 не существует или не может быть разрешено» - PullRequest
0 голосов
/ 05 ноября 2019

Я использую JSF 2.3 и Bootsfaces 3.3 в небольшом веб-приложении. Я наткнулся на сценарий, где Bootsfaces "вызывает исключение в то время как+не. Глядя на исключение, которое возникает, Bootsfaces не может найти элемент с заданным идентификатором, который должен быть обновлен в фазе ответа рендеринга («ajaxUpdateMe» в приведенных ниже примерах).

Я играл на странице xhtmlприбить, где актуальная проблема и для меня это выглядити ajaxafiedплохо работает вместе. Это (урезанная версия) используемой страницы xhtml (минус и части):

<h:body>
  <b:form id="formTable">
    <!-- iterate over list of objects -->
    <ui:repeat value="#{testBean.list}" var="element">
      <b:row>
        <b:column><h:outputText id="ajaxUpdateMe" value="#{element.name}" /></b:column>
      </b:row>
      <b:row>
        <b:column>
          <!-- iterate over another list -->
          <h:dataTable value="#{element.innerList}" var="inner">
            <h:column>
              <b:commandButton ajax="true" value="submit"
                   action="#{testBean.submit(element)}"
                   update=":#{component.namingContainer.parent.namingContainer.clientId}:ajaxUpdateMe"
                   process="@this" />
            </h:column>
          </h:dataTable>
        </b:column>
      </b:row>
    </ui:repeat>
  </b:form>
</h:body>

Когда я пытаюсь получить доступ к странице xhtml через браузер (GETзапрос), затем немедленно возникает исключение, которое выглядит следующим образом (сокращено для краткости):

Caused by: javax.faces.FacesException: Invalid search expression: formTable:j_idt4:0:ajaxUpdateMe The subexpression 0 doesn't exist, or it can't be resolved. net.bootsfaces.component.commandButton.CommandButton  formTable:j_idt4:0:j_idt9:0:j_idt13  Additional information: ID not found: 0 search expression: formTable:j_idt4:0:ajaxUpdateMe
    at net.bootsfaces.expressions.ExpressionResolver.translateSearchExpressionToId(ExpressionResolver.java:143)
    at net.bootsfaces.expressions.ExpressionResolver.getComponentId(ExpressionResolver.java:89)
    at net.bootsfaces.expressions.ExpressionResolver.getComponentIDs(ExpressionResolver.java:50)
    at net.bootsfaces.expressions.ExpressionResolver.getComponentIDs(ExpressionResolver.java:44)
    at net.bootsfaces.component.ajax.AJAXRenderer.generateAJAXCallForClientBehavior(AJAXRenderer.java:582)
    at net.bootsfaces.component.ajax.AJAXRenderer.generateBootsFacesAJAXAndJavaScript(AJAXRenderer.java:233)
    at net.bootsfaces.component.ajax.AJAXRenderer.generateBootsFacesAJAXAndJavaScript(AJAXRenderer.java:177)
    at net.bootsfaces.component.commandButton.CommandButtonRenderer.encodeBegin(CommandButtonRenderer.java:120)
    at javax.faces.component.UIComponentBase.encodeBegin(UIComponentBase.java:892)
    at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:307)
    at com.sun.faces.renderkit.html_basic.GroupRenderer.encodeChildren(GroupRenderer.java:114)
    at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:918)
    at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:309)
    at com.sun.faces.renderkit.html_basic.TableRenderer.renderRow(TableRenderer.java:398)
    at com.sun.faces.renderkit.html_basic.TableRenderer.encodeChildren(TableRenderer.java:161)

Я заменил командную кнопку из Bootsfaces следующим кодом:

<h:commandButton value="submit"
                 action="#{testBean.submit(element)}">
  <f:ajax render=":#{component.namingContainer.parent.namingContainer.clientId}:ajaxUpdateMe"
           execute="@this"/>
</h:commandButton>

Теперь страница загружается нормально, а командная кнопка делает то, что должна делать. Проверяя источник html-страницы в браузере, я вижу, что элемент, упомянутый в сообщении об исключении formTable:j_idt4:0:ajaxUpdateMe, действительно есть.

Я обнаружил ошибку в Bootsfaces или я что-то не так делаю? Кто-нибудь знает обходной путь, где я все еще могу использовать командную кнопку из Bootsfaces?

1 Ответ

0 голосов
/ 06 ноября 2019

Похоже, что распознаватель BootsFaces ID борется с 0 в formTable:j_idt4:0:ajaxUpdateMe. Вы можете попытаться добавить id="elements к пользовательскому интерфейсу: repeat, а затем напрямую обратиться к целевому компоненту с помощью :formTable:elements:ajaxUpdateMe.

<h:body>
  <b:form id="formTable">
    <!-- iterate over list of objects -->
    <ui:repeat id="elements" value="#{testBean.list}" var="element">
      <b:row>
        <b:column><h:outputText id="ajaxUpdateMe" value="#{element.name}" /></b:column>
      </b:row>
      <b:row>
        <b:column>
          <!-- iterate over another list -->
          <h:dataTable value="#{element.innerList}" var="inner">
            <h:column>
              <b:commandButton ajax="true" value="submit"
                   action="#{testBean.submit(element)}"
                   update=":#formTable:elements:ajaxUpdateMe"
                   process="@this" />
            </h:column>
          </h:dataTable>
        </b:column>
      </b:row>
    </ui:repeat>
  </b:form>
</h:body>

Моя среда IDE не предлагает ui:repeat на самом деле имеет атрибут id, но это как-то работает для меня.

В качестве альтернативы вы можете добавить к своей кнопке стандартный f:ajax:

<b:commandButton ajax="true" value="submit" process="@this">
    <f:ajax render=":#{component.namingContainer.parent.namingContainer.clientId}:ajaxUpdateMe" />
</b:commandButton>

Я не уверен, следует ли это считать ошибкой. Вы можете поднять это в их системе отслеживания проблем

...