【发布时间】:2012-04-23 17:28:00
【问题描述】:
我想创建带有标签的 JSF 页面。像this 这样的东西。但我想知道如果我选择使用 Jquery 来执行此操作,我可以实现延迟加载 - 当我单击 JSF 页面上的选项卡时,会在打开选项卡时生成内容。是否可以在纯 JSF 中实现选项卡的延迟加载?而且我想在这两种情况下我都可以轻松实现 AJAX。
最好的祝福
【问题讨论】:
我想创建带有标签的 JSF 页面。像this 这样的东西。但我想知道如果我选择使用 Jquery 来执行此操作,我可以实现延迟加载 - 当我单击 JSF 页面上的选项卡时,会在打开选项卡时生成内容。是否可以在纯 JSF 中实现选项卡的延迟加载?而且我想在这两种情况下我都可以轻松实现 AJAX。
最好的祝福
【问题讨论】:
Primefaces Tabview 组件支持延迟加载。
来自展示的引述:
选项卡内容也可以使用 ajax 延迟加载,当动态时 属性设置为“true”只有活动选项卡的内容将是 呈现并单击惰性选项卡将获取选项卡内容 阿贾克斯。这种行为对于节省带宽和减小页面大小很方便 在处理具有大量内容的选项卡时。p>
展示中的快速示例:
<h:form id="form">
<p:tabView id="tabView" dynamic="true" cache="true">
// tabs
</p:tabView>
</h:form>
cache 属性用于防止在选项卡之间切换时 ajax 重新加载选项卡内容。
【讨论】:
用 jQuery UI 实现一个 ajax 选项卡根本不是问题。
查看jQuery Tabs with ajax here的文档并点击“查看源代码”找到你需要的代码。
【讨论】:
您可以查看 Core Java Server Faces third edition 第 339 页一书,了解如何使用 h:panelGrid 实现简单的选项卡。
输出是这样的:
这是书中的代码示例:
...
<h:form>
<h:panelGrid styleClass="tabbedPane" columnClasses="displayPanel">
<!-- Tabs -->
<f:facet name="header">
<h:panelGrid columns="4" styleClass="tabbedPaneHeader">
<h:commandLink tabindex="1"
title="#{msgs.jeffersonTooltip}"
styleClass="#{tp.jeffersonStyle}"
actionListener="#{tp.jeffersonAction}">
#{msgs.jeffersonTab}
</h:commandLink>
...
</h:panelGrid>
</f:facet>
<!-- Tabbed pane content -->
<ui:include src="washington.xhtml" />
<ui:include src="roosevelt.xhtml" />
<ui:include src="lincoln.xhtml" />
<ui:include src="jefferson.xhtml" />
</h:panelGrid>
</h:form>
...
这是描述:
The tabbed pane is implemented with h:panelGrid. Because we do not specify
the columns attribute, the panel has one column. The panel’s header—defined
with an f:facet tag—contains the tabs, which are implemented with another
h:panelGrid that contains h:commandLink tags for each tab. The only row in the panel
contains the content associated with the selected tab.
When a user selects a tab, the associated action listener for the command link is
invoked and modifies the data stored in the backing bean. Because we use a
different CSS style for the selected tab, the styleClass attribute of each h:commandLink
tag is pulled from the backing bean with a value reference expression.
As you can see from the top picture in Figure 8–11, we have used the title
attribute to associate a tooltip with each tab. Another accessibility feature is the
ability to move from one tab to another with the keyboard instead of the
mouse. We implemented that feature by specifying the tabindex attribute for
each h:commandLink.
The content associated with each tab is statically included with the JSP include
directive. For our application, that content is a picture and some text, but
you could modify the included JSF pages to contain any set of appropriate
components. Notice that even though all the JSF pages representing content are
included, only the content associated with the current tab is rendered. That is
achieved with the rendered attribute—for example, jefferson.xhtml looks like this:
Putting It All Together
<h:panelGrid columns="2" columnClasses="presidentDiscussionColumn"
rendered="#{tp.jeffersonCurrent}">
<h:graphicImage value="/images/jefferson.jpg"/>
<span class="tabbedPaneContent">"#{msgs.jeffersonDiscussion}"</span>
</h:panelGrid>
Figure 8–12 shows the directory structure for the tabbed pane application and
Listings 8–14 through 8–17 show the most important files.
不幸的是,我不知道如何在这段代码中添加延迟加载和 AJAX 支持。
【讨论】:
注意:如果您希望标签 bean 成为会话范围,请阅读答案底部的说明...
由于您不想使用任何第三方库,这里是一个 PureJSF + jQuery 示例
JSF + Jquery + Ajax 延迟加载 + 查看 Scope Bean 示例...
B.T.W 这是它最终的样子:
当您单击每个选项卡时,您可以查看 Web 服务器控制台以查看 @PostConstruct 和 @PreDestroy 的打印输出...
选项卡的内容 - xhtml 页面及其 bean 将在选项卡单击时加载(延迟加载),并在单击其他选项卡时销毁,
我建议你创建一个新项目并慢慢将所有文件放入其中并开始播放并查看它...它 100% 工作,但我放置了一些打印输出只是为了看看它真的工作...... .
这个例子非常简单直接......
首先转到jQueryUI and download it(1.8.18)
并将jquery-1.7.1_.min.js 和jquery-ui-1.8.18.custom.min.js 放入WebContent\resources\js 和jquery-ui-1.8.18.custom.css 中WebContent\resources\css
现在到其他文件...
myTabs.xhtml
<!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:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:c="http://java.sun.com/jsp/jstl/core">
<h:head>
<h:outputScript library="js" name="jquery-1.7.1_.min.js" target="head" />
<h:outputScript library="js" name="jquery-ui-1.8.18.custom.min.js" target="head" />
<h:outputStylesheet library="css" name="jquery-ui-1.8.18.custom.css" target="head" />
<h:outputScript library="js" name="mytabs.js" target="head" />
</h:head>
<h:body>
<f:view>
<h:form prependId="false">
<h:panelGroup id="tabs" layout="block">
<ul>
<c:forEach items="#{myTabs.tabs}" var="tab">
<li><a href="##{tab.tabid}" onclick="$('#button_#{tab.tabid}').click()">#{tab.tabid}</a></li>
<h:commandButton id="button_#{tab.tabid}" value="TabClick" action="#{myTabs.switchPages(tab.tabid)}" style="display:none">
<f:ajax render="tabs"></f:ajax>
</h:commandButton>
</c:forEach>
</ul>
<c:forEach items="#{myTabs.tabs}" var="tab">
<h:panelGroup id="#{tab.tabid}" layout="block" rendered="#{tab.tabid eq myTabs.selectedTab}">
<ui:include src="#{tab.tabfilename}"></ui:include>
</h:panelGroup>
</c:forEach>
</h:panelGroup>
</h:form>
</f:view>
</h:body>
</html>
MyTabs.java
package pack;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
@ManagedBean
@SessionScoped
public class MyTabs{
@PostConstruct
public void init(){
tabs = new ArrayList<MyTabObject>();
tabs.add(new MyTabObject("tab1.xhtml", "tab1"));
tabs.add(new MyTabObject("tab2.xhtml", "tab2"));
tabs.add(new MyTabObject("tab3.xhtml", "tab3"));
}
String selectedTab="tab1";
public String getSelectedTab() {
return selectedTab;
}
public void setSelectedTab(String selectedTab) {
this.selectedTab = selectedTab;
}
public String switchPages(String selTab) {
selectedTab = selTab;
return "myTabs.xhtml";
}
List<MyTabObject> tabs;
public List<MyTabObject> getTabs() {
return tabs;
}
public void setTabs(List<MyTabObject> tabs) {
this.tabs = tabs;
}
}
MyTabObject
package pack;
public class MyTabObject{
String tabfilename;
String tabid;
public String getTabfilename() {
return tabfilename;
}
public void setTabfilename(String tabfilename) {
this.tabfilename = tabfilename;
}
public String getTabid() {
return tabid;
}
public void setTabid(String tabid) {
this.tabid = tabid;
}
public MyTabObject(String tabfilename, String tabid) {
super();
this.tabfilename = tabfilename;
this.tabid = tabid;
}
}
Tab1Page,(Tab2Page和Tab3Page完全一样,只是把所有地方的数字都改了)
package pack;
import java.io.Serializable;
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
@ManagedBean
@ViewScoped
public class Tab1Page implements Serializable{
/**
*
*/
private static final long serialVersionUID = 254415216070877770L;
// Constants
public final static String hashKey = "tab1PageTab";
public String actionString = "";
@PostConstruct
public void post(){
Format formatter;
Date date = new Date();
// Time formate 01:12:53 AM
formatter = new SimpleDateFormat("hh:mm:ss a");
tabName = formatter.format(date);
System.out.println("Tab1Page\t"+tabName+"\t@PostConstruct...");
}
@PreDestroy
public void destroy(){
Format formatter;
Date date = new Date();
// Time formate 01:12:53 AM
formatter = new SimpleDateFormat("hh:mm:ss a");
tabName = formatter.format(date);
System.out.println("Tab1Page\t"+tabName+"\t@PreDestroy...");
}
String tabName;
public String getTabName() {
return this.getClass().getName().substring(this.getClass().getName().lastIndexOf("."))+"\t"+tabName;
}
public void setTabName(String tabName) {
this.tabName = tabName;
}
public String getActionString() {
return actionString;
}
public void setActionString(String actionString) {
this.actionString = actionString;
}
}
tab1.xhtml(tab2.xhtml 和 tab3.xhtml 完全一样 - 只是替换数字)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:c="http://java.sun.com/jsp/jstl/core">
<h:panelGroup>
<h:form>
<h:outputText value="#{tab1Page.tabName}" />
</h:form>
</h:panelGroup>
</ui:composition>
到最后一个文件
mytabs.js(将其放在 WebContent\resources\js 中)
$(document).ready(function () {
$("#tabs").tabs();
});
$(window).load(function() {
jsf.ajax.addOnEvent(function (data) {
if (data.status === "success") {
$("#tabs").tabs();
}
});
});
为了使用 Session Scope Beans:
MyTabs.java 中的方法switchPages 应该是void 并且不返回任何东西,像这样
public void switchPages(String selTab) {
selectedTab = selTab;
}
【讨论】: