在
Ajax级联选择框:以中国的省市地区三级联动选择为例
篇中介绍了Rails应用Ajax技术实现三级联动菜单,本篇将介绍Rails应用ExtJs技术实现三级联动菜单。
需求: 允许用户只选择省、市、地区三者之一,同时
为了简化数据库表的结构,只设计一个字段(如, cid字段)来保留省、市、地区三者之一的id,这与
Ajax级联选择框
有所不同,后者是用三个字段来分别保存省、市、地区的id。
同时也是测试Rails应用ExtJs技术的效果。
步骤:
①、工具准备:1、 安装Rails插件acts_as_nested_set(附件)
2、下载ext的js文件包(附件),
将其解压到public目录下
②、确定数据库的设计,下面将省市地区数据以如下方式存入数据库的cities表(附件):
+--------+--------------+-----------+------+------+
| id | name | parent_id | lft | rgt |
+--------+--------------+-----------+------+------+
| 4122 | 中国 | 1 | 1 | 6464 |
| 110000 | 北京市 | 0 | 2 | 39 |
| 110101 | 东城区 | 110000 | 3 | 4 |
| 110102 | 西城区 | 110000 | 5 | 6 |
| 110103 | 崇文区 | 110000 | 7 | 8 |
| 110104 | 宣武区 | 110000 | 9 | 10 |
+--------+--------------+-----------+------+------+
这个数据库表是在Ajax级联选择框
篇的附件中的cities表基础上,结合ext tree的需要设计的,其中parent_id为父节点id、lft为左节点id、rgt为右节点id。至于如何生成parent_id、lft和rgt的值
,具体请步骤为:遍历citis -> 用sql 查出 下级 ->调用acts_as_nested_set插件的
add_child(child_object)方法,那么就会自动生成
parent_id、lft和rgt的值。
例如:参考: http://www.iteye.com/topic/177501
root = Category.create(
:text
=>
'Root'
)
root.add_child(c1 = Category.create(
:text
=>
'Child 1'
))
c1.add_child(Category.create(
:text
=>
'Child 1.1'
))
③、在cities表对应的模型内添加代码,声明、使用acts_as_nested_set插件,如下面代码片段所示:
class City < ActiveRecord::Base
acts_as_nested_set
def children_count
return (self[right_col_name] - self[left_col_name] - 1)/2
end
def leaf?
unknown? || children_count == 0
end
............
end
④、然后修改相应的Controller:
class CitiesController < ApplicationController
def cities_tree
(id = params[:node])
cdata = Array.new
c = City.find_all_by_parent_id( id || 1,:order => 'lft')
cdata = get_tree(c, nil)
render :text=>cdata.to_json
, :layout=>false
end
def get_tree(c, parent)
data = Array.new
c.each { |cc|
if !cc.leaf?
if data.empty?
data = [{"text" => cc.name,"id" => cc.id,
"cls" => "folder" ,"leaf" => false }]
else
data.concat([{"text" => cc.name,"id" => cc.id,
"cls" => "folder" ,"leaf" => false}])
end
else
data.concat([{"text" => cc.name,"id" => cc.id,
"cls" => "file","leaf" => true}])
end
}
return data
end
def index
@cities = City.all
respond_to do |format|
format.html
format.xml { render :xml => @cities }
end
end
end
⑤、 最后修改相应的视图:如公司所在地的选择框,首先所在地被保存在companies表的cid字段,那么在views/companies/new.html.erb,就可应用Ext.tree控件,实现公司所在地的树型选择,如下代码片段所示:
首先引入Ext的js文件:<%= javascript_include_tag :defaults %>
<%= stylesheet_link_tag "../ext/resources/css/ext-all.css" %>
<%= javascript_include_tag "../ext/adapter/prototype/ext-prototype-adapter.js" %>
<%= javascript_include_tag "../ext/ext-all.js" %>
<%= javascript_include_tag "../ext/ComboBoxTree.js" %>
其次使用ComboBoxTree生成下拉选择框:
<div id="comboboxtree" ></div>
<% javascript_tag do %>
Ext.onReady(function(){
var comboBoxTree = new Ext.ux.ComboBoxTree({
renderTo : 'comboboxtree',
name : 'company[cid]', //companies表的
cid
字段
id : 'company_cid', //companies表的
cid
字段
width : 250,
border: true,
valueField:"id",
tree : new Ext.tree.TreePanel({
loader: new Ext.tree.TreeLoader({
url:'/cities/cities_tree',
requestMethod:'GET',
baseParams:{format:'json'
}
}),
animate:true,
enableDD:true,
border:false,
containerScroll: false,
rootVisible:false ,
root: new Ext.tree.AsyncTreeNode({text: '中国',id:'0'})
})
});
comboBoxTree.render('comboboxtree');
});
<% end %>
上面的代码,是参照ExtJs官方网站上使用Ext.Tree控件的例子,修改的只是,数据提供部分,即上面的粗体部分。
下图是上代码的显示效果:用户选择了:
辽宁省 --> 鞍山市 --> 岫岩满族自治县
最终保存到companies
表的
cid
字段的值就是
"岫岩满族自治县" 对应于cities表里的id值,当然用户也可以只选择 " 辽宁省 --> 鞍山市" 或 "辽宁省" ,那么相应存入数据库的就是" 鞍山市" 的id 或 " 辽宁省" 的id。
而显示的时候,只要在cities表对应的Model添加一个encode()方法,利用acts_as_nested_set插件的self_and_ancestors来找到它的上级信息,如下代码片段所示:
def self.encode(id)
str = ''
if not id.nil? then
begin
self.self_and_ancestors.each {|c|
if not (c.name.include? '中国')
str += c.name
end
}
return str
rescue Exception => exc
logger.error("#{exc.message}")
return ""
end
end
end
视图里调用<%=h City.encode(@company.cid ) %>,那么虽然@company.cid = "岫岩满族自治县" 的id,但是显示的却是完整信息:"辽宁省鞍山市岫岩满族自治县"。
可见,在Rails项目中使用ExtJs技术是没问题的,而且
效果符合RIA(富客户端)的要求。
参考资料:http://www.iteye.com/topic/177501
http://www.iteye.com/topic/76860
http://api.rubyonrails.org/classes/ActiveRecord/Acts/NestedSet/ClassMethods.html
- 大小: 22.1 KB
分享到:
相关推荐
Rails::API 是 Rails 的精简版本,针对不需要使用完整 Rails 功能的开发者。 Rails::API 移除了 ActionView 和其他一些渲染功能,不关心Web前端的开发者可更容易、快速地开发应用程序,因此运行速度比正常的 Rails ...
Node.js入门手册主要介绍了当前最流行的Web开发框架,这些框架为开发者提供了构建高效、可测试且易于维护的应用程序的工具。以下是一些重要的框架及其特点: 1. actionHero:一个最小化的事务API框架,支持socket和...
Ruby on Rails印度尼西亚主页 该存储库是网站上内容的结果:地位一般说明不要忘记捆绑Gemfile资源: $ bundle install要构建源代码: $ jekyll build要查看源代码服务,请执行以下操作: $ jekyll serve您可以在耙上...
Ruby on Rails:部署Rails应用至Heroku.docx
rails.vim提供了常用的一些命令,可以帮助开发,例如:Rgenerate, Rake, Rfind,RTview等,很方便,也很实用。 安装方法: 拷贝 autoload/rails.vim, plugin/rails.vim, 和 doc/rails.txt 到 ~/.vim 目录. ...
With this fully revised new edition, take a holistic view of full-stack development to create usable, high-performing applications with Rails 5. Rails is a great tool for building web applications, ...
webpack-rails, 将 web pack与你的Ruby on Rails 应用程序集成 不再维护webpack-rails 不再被维护。... web pack-railsweb pack 为你提供了将 web pack集成到现有的Ruby on Rails 应用程序中的工具。它很乐
rails_apps_composer, 一个 gem,为 Rails 启动应用程序创建 Rails 应用程序模板 Rails 应用编辑器 Rails 应用程序编辑器 gem 安装一个 命令行 工具来从"食谱"的Collection 组装 Rails 应用程序。"你可以使用 rails_...
在这个“rails.girls.utrecht.2015”压缩包中,我们主要关注的是JavaScript这一标签。JavaScript是一种广泛应用于Web开发的脚本语言,它在前端开发中扮演着核心角色,用于增强用户交互、处理数据、创建动态内容等。...
在 Rails 应用中,模型负责数据操作,视图负责展示,控制器则作为两者之间的桥梁,处理用户请求并协调数据展示。 二、Exporter 概念 数据导出是 web 应用中常见的需求,例如生成 CSV、Excel 或 PDF 文件供用户下载...
10. **Rails插件**:介绍Rails社区中流行的插件,包括如何查找、安装和自定义插件,以增强应用的功能或简化开发过程。 11. **调试、测试和基准测试**:教授如何调试Rails应用,如何编写单元测试和集成测试,以及...
在本篇内容中,我们将深入探讨如何利用Ruby on Rails(简称Rails)这一强大的Web应用程序框架来构建可伸缩且易于维护的RESTful API。Rails以其简洁优雅的语法、高效的开发速度以及良好的社区支持而闻名,这使得它...
Ruby on Rails:Rails与JavaScript集成.docx
- **MVC架构**:文档中提到的MVC是Rails的核心架构模式,它将应用程序分为三个主要的组件:模型(Model)、视图(View)和控制器(Controller)。这种分离使得代码更加模块化,易于管理和扩展。 ### Rails应用的...
类似于Rails的url帮助器, rails.macro为每个已定义的路由提供方法,即<routeName>_path和<routeName>_url 。 您可以从导出的Routes对象中调用它们。 基本用法 给定Rails路线my_cool_thing config / routes.rb ...
$ cd rails.terakoya.io $ bundle install 开机 $ bundle exec middleman server 手动构建和发布 $ git pull --rebase origin master $ bundle exec middleman build $ bubdle exec middleman deploy