带有switchType ajax和a4j:status的RichFaces选项卡面板



我努力实现的目标

我有一个带有switchType="client"rich:tabPanel,其中一个选项卡已将其switchType设置为ajax,因为加载其数据是一项昂贵的操作。当我点击这个Ajax选项卡时,我希望它的标题更改为正在加载,表示点击已被识别。完成加载后,标题应切换回Ajax选项卡

[Client Tab] [Ajax Tab]
<click on 'Ajax Tab'>
[Client Tab] [Loading...]
<wait...>
[Client Tab] [Ajax Tab]
<click on 'Client Tab'>
[Client Tab] [Ajax Tab]

问题描述

事实上,上面描述的大多数操作都如预期的那样,我唯一的问题是,当我从Ajax选项卡导航到任何其他选项卡时,Ajax选项卡的标题会切换回加载

[Client Tab] [Ajax Tab]
<click on 'Ajax Tab'>
[Client Tab] [Loading...]
<wait...>
[Client Tab] [Ajax Tab]
<click on 'Client Tab'>
[Client Tab] [Loading...]

研究

我在RichFaces的JIRA中发现了一个问题,但这个问题从3.2.1版本开始就被修复了。此外,我在谷歌上搜索了几个小时,但没有发现任何类似的问题。

环境

  • Tomcat 7.0.30
  • Mojarra 2.1.12
  • RichFaces 4.2.2.Final

代码(减少)

JSF

<ui:composition template="WEB-INF/templates/default.xhtml">
<ui:define name="content">
<h:form id="form">
<rich:tabPanel id="tabPanel" switchType="client">
<rich:tab id="clientTab">
<f:facet name="header">
<h:outputText value="Client Tab" />
</f:facet>
<h:outputText value="Foo" />
</rich:tab>
<rich:tab id="ajaxTab" switchType="ajax" status="ajaxTabStatus">
<f:facet name="header">
<a4j:status id="ajaxTabStatus">
<f:facet name="start">
<h:outputText value="Loading..." />
</f:facet>
<f:facet name="stop">
<h:outputText value="Ajax Tab" />
</f:facet>
</a4j:status>
</f:facet>
<h:outputText value="#{bean.value}" />
</rich:tab>
</rich:tabPanel>
</h:form>
</ui:define>
</ui:composition>

Ajax选项卡的BackingBean

@ManagedBean
@ViewScoped
public class Bean implements Serializable {
private static final long serialVersionUID = -8405248908693334970L;
private String value = "noValue";
private static final Logger log = LoggerFactory.getLogger(Bean.class);
@PostConstruct
public void init() {
log.info("Init bean.");
value = getDummyValueWithFakeDelay();
}
public String getValue() {
log.info("Get value.");
return value;
}
private String getDummyValueWithFakeDelay() {
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
}
return DateFormat.getTimeInstance().format(new Date());
}
}

更新1:

我发现a4j:status的标识符(我的意思是你指定的<rich:someTag ... status="someStatus" />)不是它的id,而是它的name属性。因此,我的a4j:status只适用于该页面上的每个Ajax请求。不过,给它一个名字并使用这个命名状态是行不通的,因为现在什么都没发生。

<rich:tab id="ajaxTab" switchType="ajax" status="ajaxTabStatus">
<f:facet name="header">
<a4j:status id="ajaxTabStatus" name="ajaxTabStatus">
<f:facet name="start">
<h:outputText value="Loading..." />
</f:facet>
<f:facet name="stop">
<h:outputText value="Ajax Tab" />
</f:facet>
</a4j:status>
</f:facet>
<h:outputText value="#{bean.value}" />
</rich:tab>

更新2:

我还发现了另一种方法,使用onbeginoncomplete属性以及一些代码,如:

<rich:tab id="ajaxTab" switchType="ajax"
onbegin="#{rich:component('ajaxTab')}.?"
oncomplete="#{rich:component('ajaxTab')}.?">

好吧,正如你所看到的,我还没有找到操纵选项卡标题的方法(我也没有找到任何有用的文档来说明我可以使用rich:组件做什么)。

我对RichFaces 4.x不是很熟悉。然而,这就是RichFaces 3中的操作方法
假设这是tabPanel

<h:form>
<rich:tabPanel>
<rich:tab label="Client Tab" switchType="client">
Tab - client
</rich:tab>
<rich:tab label="Ajax Tab" id="ajaxTab" switchType="ajax" ontabenter="changeLabel(event)">
<h:outputText value="#{bean.value}" />
</rich:tab>
</rich:tabPanel>
</h:form>

注意ajax选项卡中的ontabenter事件。

现在你的脚本应该是这样的。

<script>
function changeLabel(tabId) {
var tabLabel = event.target || event.srcElement;
tabLabel.innerHTML = 'Loading...';
}
</script>

我对RF4了解不多。但是,在RF3中,不需要将oncomplete事件添加到选项卡中。

我使用richfaces 4.3.7执行下面的代码。这似乎奏效了。(我显示加载面板,而不是修改选项卡标题。)

<a4j:status oncomplete="#{rich:component('busy')}.hide()"
onerror="#{rich:component('busy')}.hide()"
onbegin="#{rich:component('busy')}.show()">
<rich:popupPanel id="busy" modal="true" moveable="false"
resizeable="false" autosized="true">
<h:panelGrid styleClass="alignCenter" width="100%" id="busyPanel"
columns="1" border="0" cellpadding="0" cellspacing="2">
<h:outputLabel value="Loading..." />
</h:panelGrid>
</rich:popupPanel>
</a4j:status>
<h:form>
<rich:tabPanel switchType="ajax" 
oncomplete="#{rich:component('busy')}.hide()" 
onerror="#{rich:component('busy')}.hide()"
onbegin="#{rich:component('busy')}.show()"
>
<rich:tab label="Client Tab" switchType="client">
Tab - client
</rich:tab>
<rich:tab label="Ajax Tab" id="ajaxTab" >
<h:outputText value="#{bean.value}" />
</rich:tab>
</rich:tabPanel>
</h:form>

最新更新