Проблема с ajax в составном компоненте, изначально отрендеренном = false

Я столкнулся с проблемой использования Ajax в составных компонентах (в отличие от Ajaxification пользовательских компонентов с использованием атрибута clientBehavior).

Я столкнулся со старой проблемой, когда цель запроса ajax должна присутствовать в DOM при первоначальном отображении страницы.

Пользовательский компонент имеет некоторые внутренние взаимодействия ajax, но доступ к нему осуществляется из div, который изначально имеет значение rendered=false, и ajax перестает работать, обычно без каких-либо сообщений об ошибках в журнале сервера.

Этот простой пример демонстрирует проблему. Если для свойства showPanel изначально установлено значение true, вы можете ввести какой-либо текст, нажать на ссылку push и увидеть обновленный текст на экране — все в порядке. Если для showPanel установлено значение false, вы можете нажать кнопку Toggle, которая отображает панель, но ссылка «push» больше не работает.

Ясно, что было бы полезно, если бы этот композит мог действовать как дискретный компонент, полностью инкапсулированный.

Кто-нибудь знает, есть ли способ обойти это? Я только что потратил целую вечность на написание компонента «все поют все танцуют», и в первый раз, когда я пытаюсь его использовать, он не работает!

Спасибо.

Mojarra 2.0.4 Glassfish 3.0.1 IE8/Chrome.

index.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:sqcc="http://java.sun.com/jsf/composite/sqcc"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">
    <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body>
        <h:form prependId="false">
            <h:panelGroup id="ajaxTarget">
                <h:panelGroup rendered="#{indexBean.showPanel}">
                    <sqcc:testcomp value="#{indexBean.text}"/>
                </h:panelGroup>
            </h:panelGroup>
            <h:commandButton value="Toggle" action="#{indexBean.togglePanel}">
                <f:ajax render="ajaxTarget"/>
            </h:commandButton>
        </h:form>
    </h:body>
</html>

ресурсы/sqcc/testcomp.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:cc="http://java.sun.com/jsf/composite"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">

    <!-- INTERFACE -->
    <cc:interface>
        <cc:attribute name="value"/>
    </cc:interface>

    <!-- IMPLEMENTATION -->
    <cc:implementation>
        <div id="#{cc.clientId}">
            <h:form prependId="false">
                <h:inputText id="input1" value="#{cc.attrs.value}"/>
                <h:outputText id="output1" value=" #{cc.attrs.value}"/><br/>
                <h:commandLink value="push">
                    <f:ajax execute="input1" render="output1"/>
                </h:commandLink>
            </h:form>
        </div>
    </cc:implementation>
</html>

IndexBean.java

import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

@ManagedBean
@ViewScoped
public class IndexBean implements Serializable {

    public IndexBean() {
    }

    private boolean showPanel = true;
    private String text;

    public String togglePanel() {
        showPanel = !showPanel;
        return null;
    }

    public boolean isShowPanel() {
        return showPanel;
    }

    public void setShowPanel(boolean showPanel) {
        this.showPanel = showPanel;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }
}

[конец]


person Oversteer    schedule 19.02.2011    source источник


Ответы (1)


На самом деле не следует отвечать на мой собственный вопрос, но я вернулся к этому через несколько недель. Большая ошибка в моем первоначальном посте заключалась в том, что цель Ajax должна отображаться только при загрузке первой страницы, как всем известно. Должно быть, я устал.

Поведение, продемонстрированное моим тестовым приложением, при котором «ajax в составном компоненте» не будет работать, если внешний контейнер не был изначально визуализирован, было на самом деле правильным и воспроизводимым, но только если логика внутри реализации составного компонента находится внутри его собственной формы. . Выньте форму h: из cc, и все в порядке.

Брендан.

person Oversteer    schedule 14.03.2011
comment
Спасибо за продолжение, и вы абсолютно ДОЛЖНЫ отвечать на свой вопрос, если узнаете больше и найдете ответ/решение. Гораздо лучше, чем отказаться от него; таким образом, другие тоже могут учиться у него. Спасибо, что нашли время. - person Craig Ringer; 10.05.2012