首先下载ext的js包,可以到http://extjs.com/下载,现在有两个版本1.0和2.0,如果下载后的包名为ext1.0或者2.0则去掉版本号,统一改成ext,方便以后写路径名称;这个ext里的资源是一个总包,如果你对这个资源包里的内容很熟悉的话,可以对资源内容进行有选择性的使用;
将改好名的ext包拷贝到项目目录/publi下,形成路径public/ext,由于ext只是一个js包,并不是rails的插件;
其他操作如下:
数据库:
- DROP TABLE IF EXISTS `nested_set_items`;
- CREATE TABLE `nested_set_items` (
- `id` int(11) NOT NULL auto_increment,
- `parent_id` int(11) default NULL,
- `lft` int(11) NOT NULL default '0',
- `rgt` int(11) NOT NULL default '0',
- `name` varchar(100) NOT NULL default '',
- PRIMARY KEY (`id`)
- );
- LOCK TABLES `nested_set_items` WRITE;
- INSERT INTO `nested_set_items` VALUES (1,NULL,1,14,'Root');
- INSERT INTO `nested_set_items` VALUES (2,1,2,7,'Child 1');
- INSERT INTO `nested_set_items` VALUES (3,2,3,4,'Child 1.1');
- INSERT INTO `nested_set_items` VALUES (4,2,5,6,'Child 1.2');
- INSERT INTO `nested_set_items` VALUES (5,1,8,13,'Child 2');
- INSERT INTO `nested_set_items` VALUES (6,5,9,10,'Child 2.1');
- INSERT INTO `nested_set_items` VALUES (7,5,11,12,'Child 2.2');
- UNLOCK TABLES;
控制器:
- class CategoriesController < ApplicationController
- def index(id = params[:node])
- puts id
- respond_to do |format|
- format.html # render static index.html.erb
- format.json { render :json => Category.find_children(id)}
- end
- end
- end
model:
如果根据网上的demo来实现的话会出现node id不正确,id会出现类似ynode-xxx(xxx为数字),导致程序错误;本想去修改js的,但是js内容很庞大就放弃了,从而在mode里组织node的数据,而后觉得这种形式更好一些,可以根据业务逻辑进行控制;
- class Category < ActiveRecord::Base
- establish_connection :localhost
- acts_as_nested_set
- #首先先得到树的根节点,再根据传过来的id找到根的子节点
- def self.find_children(start_id = nil)
- data = Array.new
- if start_id.blank?
- root_nodes
- else
- @nodes = find :all,:conditions=>"parent_id=#{start_id}"
- @nodes.each { |node|
- if leaf? node.id
- data += [{"text" => node.name, "id" => node.id, "cls" => "folder", "leaf" => false}]
- else
- data += [{"text" => node.name, "id" => node.id, "cls" => "folder", "leaf" => true}]
- end
- }
- end
- return data
- end
- #如果parent_id为空,则为树的根节点
- def self.root_nodes
- find(:all, :conditions => 'parent_id IS NULL')
- end
- def self.leaf?(nodeid)
- children = Category.find :all,:conditions=>["parent_id =?",nodeid]
- if children.size > 0
- return true;
- else
- return false;
- end
- end
- end
视图:
- <html>
- <head>
- <meta http-equiv="content-type" content="text/html;charset=UTF-8"/>
- <title>Rails Ext Tree 测试</title>
- <%= stylesheet_link_tag "../ext/resources/css/ext-all.css" %>
- <%= javascript_include_tag :defaults %>
- <%= javascript_include_tag "../ext/adapter/prototype/ext-prototype-adapter.js" %>
- <%= javascript_include_tag "../ext/ext-all.js" %>
- <%= javascript_include_tag "../ext/adapter/ext/ext-base.js" %>
- <%= javascript_include_tag "../ext/ext-all-debug.js" %>
- </head>
- <body>
- <div id="category-tree" style="padding:20px"></div>
- <% javascript_tag do -%>
- Ext.onReady(function(){
- var root = new Ext.tree.AsyncTreeNode({
- text: 'EXT测试树结构ROOT',
- draggable:false,
- id:'1'
- });
- var tree = new Ext.tree.TreePanel({
- animate:false,
- loader: new Ext.tree.TreeLoader({
- dataUrl:'/categories',
- requestMethod:'GET',
- baseParams:{format:'json',lib:'yui'}
- }),
- renderTo:'category-tree',
- root: root,
- rootVisible:true ,
- autoScroll:true,
- enableDD:false,
- containerScroll: true
- });
- tree.on('click', function(node){
- alert(node.text);
- });
- tree.setRootNode(root);
- tree.render();
- root.expand();
- });
- <% end -%>
- </body>
- </html>