Я столкнулся с проблемой использования 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;
}
}
[конец]