递归模型的前端展示将不可避免的使用到tree的结构,几番对照之后,发现tree_view似乎已经不再更新。jstree这个俄国人设计的jquery插件却生命力十足,活力四射。所以就选择这个插件进行研究。
1.搭建一个jstree的测试环境
后台使用rails,在public下创建一个目录jstree,然后将下载的jstree包中的相关内容拷贝到这个目录中:
/jstree下包含:jstree.js,jquery.js
/jstree/images:这里包含显示用的图片
/jstree/themes:这里包含各类主题,如checkbox。
这里用的版本是0.99版本(jstree版本与5月25日刚升级到1.0rc版本,变化较大,不过思路可以参考这篇文档,以后,将1.0的使用说明继续在博客中记录)
jquery的版本使用的是1.3.2,使用1.4.1好像有问题,子树不能正常显示。
2.明确目标
使用jstree插件,采用json格式,使用ajax从rails后台获取动态的子树。
前端代码:
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>jsTree » Demo » Async HTML</title>
<meta name="title" content="jsTree - jQuery tree plugin - Async HTML Demo" />
<!--<link rel="stylesheet" type="text/css" href="style.css" />
-->
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="jquery.tree.js"></script>
<link rel="stylesheet" type="text/css" href="/jstest/themes/default/style.css" />
</head>
<body class="nosidebar" >
<div id="container">
<script type="text/javascript" >
var stat = [
{ data : "Node 1",attributes : { "id" : "node_1" } },
{ attributes : { "id" : "node_2" }, data : "Node 2", state : "open"},
{ attributes : { "id" : "node_3" }, data : "Node 3", state : "closed"}
];
$(function () {
$.ajaxSetup({cache:false});//ajax 调用不使用缓存
$("#async_json_1").tree({
data : {
type : "json",
async : true,
opts : {
method : "GET",
url : "/ceshi/json_test.json"
}
},
lang:{
loading:"加载中……" //在用户等待数据渲染的时候给出的提示内容,默认为loading
},
ui:{
theme_name:'classic' //设置样式
// theme_name : "checkbox"
},
callback : {
// Make sure static is not used once the tree has loaded for the first time
onload : function (t) {
t.settings.data.opts.static = false;//让初始化数据只使用第一次
},
//n-- 节点,t是tree
beforedata : function (n, t) {
if(n == false)
t.settings.data.opts.static = stat;
else
return {parent_id : $(n).attr("id") || false} // AJAX 调用参数传递
},
oncreate :function(n,t){
}
},
//插件使用右键菜单支持自定义右键菜单
plugins:{
contextmenu:{}
// checkbox : {three_state : false }
},
rules:{multiple:"false"}
});
});
</script>
<div class="demo" id="async_json_1"></div>
</div>
</body>
</html>
解释如下:
1.javascript定义部分
var stat = [
{ data : "Node 1",attributes : { "id" : "node_1" } },
{ attributes : { "id" : "node_2" }, data : "Node 2", state : "open"},
{ attributes : { "id" : "node_3" }, data : "Node 3", state : "closed"}
];
定义了初始化的树;
同时在beforedata中进行了定义:
beforedata : function (n, t) {
if(n == false)
t.settings.data.opts.static = stat;
...
}
这里使用t.settings.data.opts.static = stat,将树进行初始化。
注:代码借鉴jstree中demo和互联网上的资料。
2.数据准备中,配置ajax
data : {
type : "json",
async : true,
opts : {
method : "GET",
url : "/ceshi/json_test.json"
}
}
使用get方式从后台获取json数据
3.准备get方式客户端发送到服务器端的数据:仍然在beforedata中进行配置
beforedata : function (n, t) {
if(n == false)
t.settings.data.opts.static = stat;
else
return {parent_id : $(n).attr("id") || false} // AJAX 调用参数传递
}
这里使用return {parent_id : $(n).attr("id") || false}为get方法准备数据
后台rails代码
创建ceshi控制器,同时建立一个json_test.json action,代码如下:
class CeshiController < ApplicationController
def json_test
# if params[:parent_id] == "node_3"
data = "[{data:\"node_1\",attributes:{id:5},state:\"closed\"},
{data:\"node_1\",attributes:{id:6},state:\"closed\"}
]"
respond_to do |format|
format.json {render :text=>data}
end
# end
end
end
解释:
1.外层if语句,为了检测客户端发出的参数是否准确;
2.创建一个data变量,它是一个字符串,是json格式,满足jstree的格式需求。
data
attributes:{id:5} //这里的id:5就是将要从用户点击树节点,要送出去的值。我们在后台可以将这个值与后台的数据库中的某个值进行对应,从而获取一个子树对应的数组,并将这个数组,变为json格式的数据,送到客户端,客户端的jstree控件进行识别,并画出子树。
3.按照这种方式也可以使用xml格式。
存在的问题:
目前只是将树可以展现出来,也就是完成了tree的read,另外create、update、delete尚未完成。看了jstree的1.0版本(变化非常大),这一块的工作似乎非常容易完成。
待续。。。近日将使用jstree的1.0版本,将心得继续放送。