在上一篇文章《Struts 2與AJAX(第一部分)》,我已經簡單地介紹了<s:tree />的一些用法,接下來我將繼續深入講解<s:tree />的使用和通過DWR實現AJAX校驗。
更多<s:tree />
在Struts 2的showcase中有兩個<s:tree />的例子,分別是靜態樹與動態樹。所謂的靜態樹即是在編寫JSP代碼時通過<s:treenode />生成樹節點。我的上一篇文章的例子就是一個典型的靜態樹。而動態樹則是在程序運行期間,Struts 2 運行時(Runtime)根據程序中的數據動態創建樹節點。雖然在兩個例子中<s:tree />的theme屬性都為“ajax”,但是從嚴格意義上來說,這兩種樹都不屬于AJAX樹,因為它們都是在輸出頁面時將全部節點加載到其中,而不是在父節點展開時通過XHR(XMLHttpRequest)獲取節點數據。
動態樹
下面我們先看一下動態樹的例子,接著再一步步地將其改造為名副其實的AJAX 樹。下例將會把WEB應用程序的目錄樹展現在JSP頁面中。因此,我需要先包裝一下java.io.File 類,代碼如下:
package tutorial;
import java.io.File;
public class FileWrapper {
private File file;
public FileWrapper(String path) {
file = new File(path);
}
public FileWrapper(File file) {
this.file = file;
}
public String getId() {
return "file_" + file.hashCode();
}
public String getName() {
return file.getName();
}
public String getAbsolutePath() {
return file.getAbsolutePath();
}
public FileWrapper[] getChildren() {
File[] files = file.listFiles();
if(files != null && files.length > 0) {
int length = files.length;
FileWrapper[] wrappers = new FileWrapper[length];
for(int i = 0; i < length; ++i) {
wrappers[i] = new FileWrapper(files[i]);
}
return wrappers;
}
return new FileWrapper[0];
}
}
清單1 src/tutorial/FileWrapper.java
之所以需要對File類進行如此包裝,是因為<s:tree />用于動態樹時,rootNode、nodeIdProperty、nodeTitleProperty 和 childCollectionProperty等屬性都必填的。
然后是Action類的代碼如下:
package tutorial;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.interceptor.ServletRequestAware;
import com.opensymphony.xwork2.ActionSupport;
public class DynamicTreeAction extends ActionSupport implements ServletRequestAware {
private static final long serialVersionUID = 1128593047269036737L;
private HttpServletRequest request;
private FileWrapper root;
public void setServletRequest(HttpServletRequest request) {
this.request = request;
}
public FileWrapper getRoot() {
return root;
}
@Override
public String execute() {
root = new FileWrapper(request.getSession().getServletContext().getRealPath("/"));
return SUCCESS;
}
}
清單2 src/tutorial/DynamicTreeAction.java
上述代碼取得WEB應用程序的根目錄的絕對路徑后,初始化FileWrapper對象root。該對象將為JSP頁面的<s:tree />的根節點。如下代碼所示:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Struts 2 AJAX - More Tree</title>
<s:head theme="ajax" debug="true" />
<script type="text/javascript">
/* <![CDATA[ */
function treeNodeSelected(arg) {
alert(arg.source.title + ' selected');
}
function treeNodeExpanded(arg) {
alert(arg.source.title + ' expanded');
}
function treeNodeCollapsed(arg) {
alert(arg.source.title + ' collapsed');
}
dojo.addOnLoad(function() {
var t = dojo.widget.byId('appFiles');
dojo.event.topic.subscribe(t.eventNames.expand, treeNodeExpanded);
dojo.event.topic.subscribe(t.eventNames.collapse, treeNodeCollapsed);
var s = t.selector;
dojo.event.connect(s, 'select', 'treeNodeSelected');
});
/* ]]> */
</script>
</head>
<body>
<h2>
Dynamic Tree Example
</h2>
<div style="float:left; margin-right: 50px;">
<s:tree id="appFiles" theme="ajax" rootNode="root"
nodeTitleProperty="name" nodeIdProperty="id"
childCollectionProperty="children" />
</div>