Зачем нужно вставлять компонент с rendered = "# {some}" в другой компонент, когда я хочу ajax-обновить его?

Итак, я нашел несколько ответов рядом с этим, и я нашел достаточно, чтобы исправить проблемы, которые у меня были. Но даже в этом случае мне любопытно понять, как это работает. Позвольте мне проиллюстрировать пример:

У меня есть страница facete .xhtml, которая выглядит так (shortned).

<h:form id="resultForm">

    <h:panelGroup class="search_form" layout="block">
        <h:inputText id="lastname" value="#{search.lastname}"/>
        <h:commandButton action="#{search.find}" value="Find">
            <f:ajax execute="lastname" render="resultDisplay"/>
        </h:commandButton>
    </h:panelGroup>

    <h:dataTable value="#{search.searchResults}" var="results" id="resultDisplay"
            rendered="#{!empty search.searchResults}">  
        <h:column>
            #{results.field}
        </h:column>
    </h:dataTable>

</h:form>

Теперь, ради бремени, я не буду публиковать весь код bean, но у меня есть что-то в этом роде:

public void find() {
    searchResults = setResults(true);
}

Где searchResults - ArrayList<Objects>. После поиска он не равен нулю - проверен в нескольких тестах (может быть нулевым, но не в тестировании, которое я выполняю).

Теперь. Это НЕ работает.

Но если я вложу dataTable внутри другого, скажем panelGroup, он будет работать.

<h:panelGroup id="resultDisplay">
    <h:dataTable value="#{search.searchResults}" var="results"
        rendered="#{!empty search.searchResults}">  
        <h:column>
            #{results.field}
        </h:column>
    </h:dataTable>
</h:panelGroup>

Теперь эти изменения позволяют всем работать нормально. Я был бы в порядке с этим... но, я думаю, я тоже ищу немного понимания. Любое понимание того, почему мне приходится влагать эти компоненты? Я, конечно, чего-то не хватает!

Ответ 1

Обновление Ajax выполняется языком JavaScript на стороне клиента. Все, к какому JavaScript имеет доступ, является деревом HTML DOM. Если JSF не отображает какой-либо компонент для вывода HTML, то в дереве HTML DOM ничего нет, которое может быть получено JavaScript при обновлении Ajax. JavaScript не может получить желаемый элемент по его идентификатору.

Это будет работать, только если вы завершите условно JSF-визуализированный компонент в другой компонент, который всегда отображается на выходе HTML и, таким образом, всегда присутствует в дереве HTML DOM и, таким образом, всегда доступен JavaScript. Ссылка на этот компонент оболочки во время рендеринга/обновления ajax.

См. также: