项目的原型界面如下,左半部分是资源的结构,右半部分是资源的表格显示。需要完善的功能是:当通过右半部分的添加,删除按钮操作资源的时候,左半部分的资源树形结构需要与之同步,并且定位到操作的节点。
原型界面截图
项目的框架:easyui+zTree。
实现思路:ajax异步刷新,当右侧添加/删除节点之后,通过ajax异步访问数据库获得最新的资源信息,重新加载zTree,然后操作zTree节点使之定位到操作的节点。
//zTree参数设置
var zTree;
var demoIframe;
var zNodes ;
var setting = {
treeId:"applicationTree",
view: {
dblClickExpand: false,
showLine: true,
selectedMulti: false
},
data: {
key:{
name:"applicationName"
},
simpleData: {
enable:true,
idKey: "id",
pIdKey: "applicationParentId",
rootPId: "0"
}
},
callback: {
onClick: zTreeOnClick,
}
};
//刷新资源树
function refreshzTree(tId){
var t = $("#tree");
$.ajax({
type:'post',
url: "queryApplicationTree",
dataType: "text",
async: false,
success: function (data) {
zNodes=eval(data);
},
error: function (msg) {
}
});
t = $.fn.zTree.init(t, setting, zNodes);
demoIframe = $("#testIframe");
demoIframe.bind("load", loadReady);
var zTree = $.fn.zTree.getZTreeObj("tree");
$("#"+tId + "_a").click();
var node = zTree.getNodeByTId(tId);
zTree.selectNode(node,false);
zTree.expandNode(node,true , false, false);//展开node一级
};
//页面加载
$(document).ready(function(){
//加载资源树
var t = $("#tree");
$.ajax({
type:'post',
url: "queryApplicationTree",
dataType: "text",
async: false,
success: function (data) {
zNodes=eval(data);
t = $.fn.zTree.init(t, setting, zNodes);
demoIframe = $("#testIframe");
demoIframe.bind("load", loadReady);
var zTree = $.fn.zTree.getZTreeObj("tree");
//首次访问主页时默认自动单击根节点
var treeNode=zTree.getNodeByParam("applicationParentId", "0");
$("#"+treeNode.tId + "_a").click();
var node = zTree.getNodeByTId(treeNode.tId);
zTree.selectNode(node,false);
zTree.expandNode(node, true, false, false);
},
error: function (msg) {
}
});
//显示根目录节点资源
var applicationId = $("#applicationPid").val();
$('#dgApplication').datagrid('load',{
pid: applicationId
});
});
function loadReady() {
var bodyH = demoIframe.contents().find("body").get(0).scrollHeight,
htmlH = demoIframe.contents().find("html").get(0).scrollHeight,
maxH = Math.max(bodyH, htmlH), minH = Math.min(bodyH, htmlH),
h = demoIframe.height() >= maxH ? minH:maxH ;
if (h < 530) h = 530;
demoIframe.height(h);
}
var url;
//打开添加对话框
function addApplication() {
//获得选择节点的tId存入隐含域中
var nodes = $.fn.zTree.getZTreeObj("tree").getSelectedNodes();
var tId = nodes[0].tId;
$("#tId").val(tId);
//打开添加应用对话框
$('#dlgApplication').dialog('open').dialog('setTitle','添加应用');
$('#fmApplication').form('clear');
var pid = $("#applicationPid").val();
url="addApplication?pid="+pid;
}
//保存新添加或者修改后的资源
function saveApplication(){
//获得选择节点的tId存入隐含域中
var nodes = $.fn.zTree.getZTreeObj("tree").getSelectedNodes();
var tId = nodes[0].tId;
// $("#tId").val(tId);
$('#fmApplication').form('submit',{
url:url,
success:function(result){
$('#dlgApplication').dialog('close');
$('#dgApplication').datagrid('reload');
//刷新资源树
refreshzTree(tId);
},
error:function(){
$.messager.alert("警告", "保存失败", "error");
}
});
}
//打开修改窗口
function editApplication(){
var row = $('#dgApplication').datagrid('getSelected');
if (row){
$('#dlgApplication').dialog('open').dialog('setTitle','修改资源');
$('#fmApplication').form('load',row);
var pid = $("#applicationPid").val();
url='modifyApplication?pid='+pid
}else{
alert("提示消息您未选中任何行!!");
}
}
//删除方法
function delApplication(){
var rows = $('#dgApplication').datagrid('getSelections');
if (!rows||rows.length==0){
$.messager.alert('提醒','请选择至少一条记录','info');
return;
}
//获得选择节点的tId存入隐含域中
var nodes = $.fn.zTree.getZTreeObj("tree").getSelectedNodes();
var tId = nodes[0].tId;
$("#tId").val(tId);
//获取选中行的id,拼接成以&分隔的字符串
var applicationIds;
$.each(rows,function(i,n){
if(i==0){
applicationIds=n.id;
}else{
applicationIds+="&"+n.id;
}
});
//二次确认删除意图
$.messager.confirm("确认", "确定删除选中的数据", function(result){
if(!result){
return ;
}
$.ajax({ //ajax 提交到controller的delApplication方法处理
type:"post",
async:false,
url:"delApplication",
data:{applicationIds:applicationIds},
dataType:"JSON", //dataType指定返回值的类型,必须与后台的返回值一致。否则无法进入success回掉
success:function(data){ //处理成功的回调函数
$('#dgApplication').datagrid('reload');
//刷新资源树
refreshzTree($("#tId").val());
},
error:function(){alert("删除失败")} //处理失败的回到函数
});
});
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
实现zTree节点显示与操作(添加,删除)同步
@Controller
public class ApplicationController {
private ApplicationBean applicationBean;
private Application application;
/**
* 显示资源管理主界面
*
* @return 主界面
*/
@RequestMapping("/applicationMain")
public String applicationMain() {
return "/applicationMain";
}
/**
* 添加应用方法
*/
@RequestMapping("/addApplication")
public void addApplication(
HttpServletRequest request, HttpServletResponse response)
throws IOException {
System.out.println("调用添加方法!需要将json串放到response!");
}
/**
* 查询资源方法,没有传入父节点时默认为根目录的节点ID
*/
@RequestMapping("/queryApplication")
public void queryApplication(HttpServletRequest request,HttpServletResponse response) throws Exception{
System.out.println("加载table中的数据!需要将json串放到response!");
}
/**
* 查询构造资源树需要的资源集合
*/
@RequestMapping("/queryApplicationTree")
public void queryApplicationTree(HttpServletRequest request,HttpServletResponse response) throws Exception{
System.out.println("加载树形结构中的数据!需要将json串放到response!");
}
/**
* 删除资源,可以批量操作
*/
@RequestMapping("/delApplication")
public void delApplication(String applicationIds,
HttpServletRequest request, HttpServletResponse response) {
System.out.println("删除数据!");
}
/**
* 修改资源
*/
@RequestMapping("/modifyApplication")
public void modifyApplication(
HttpServletRequest request, HttpServletResponse response) {
System.out.println("修改数据!");
}
public ApplicationBean getApplicationBean() {
return applicationBean;
}
public void setApplicationBean(ApplicationBean applicationBean) {
this.applicationBean = applicationBean;
}
public Application getApplication() {
return application;
}
public void setApplication(Application application) {
this.application = application;
}
多看文档很重要。其实整体上的实现思路没有什么新鲜的东西,无非就是通过ajax再一次查询数据库然后加载一次资源数而已。但是之后定位的工作全部都是通过操作zTree节点来完成的。而如果操作这些节点呢?答案就是看zTree文档。所有我们需要的东西里面都有。我们需要做的只是理出一条实现思路,然后再去文档中找到我们想要的东西,组合起来而已!