`
lzqustc
  • 浏览: 211078 次
  • 性别: Icon_minigender_1
  • 来自: 厦门
社区版块
存档分类
最新评论

Rails中应用Ext.tree:以中国的省市地区三级联动选择为例

阅读更多

在  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
  • ext.rar (461.9 KB)
  • 下载次数: 52
分享到:
评论

相关推荐

    Rails的精简版本Rails::API.zip

    Rails::API 是 Rails 的精简版本,针对不需要使用完整 Rails 功能的开发者。 Rails::API 移除了 ActionView 和其他一些渲染功能,不关心Web前端的开发者可更容易、快速地开发应用程序,因此运行速度比正常的 Rails ...

    Node.js 入门手册:那些最流行的 Web 开发框架.docx

    Node.js入门手册主要介绍了当前最流行的Web开发框架,这些框架为开发者提供了构建高效、可测试且易于维护的应用程序的工具。以下是一些重要的框架及其特点: 1. actionHero:一个最小化的事务API框架,支持socket和...

    rails-id.github.io:在| Ruby on Rails印度尼西亚主页

    Ruby on Rails印度尼西亚主页 该存储库是网站上内容的结果:地位一般说明不要忘记捆绑Gemfile资源: $ bundle install要构建源代码: $ jekyll build要查看源代码服务,请执行以下操作: $ jekyll serve您可以在耙上...

    Ruby on Rails:部署Rails应用至Heroku.docx

    Ruby on Rails:部署Rails应用至Heroku.docx

    VIM的Rails编辑插件rails.vim.zip

    rails.vim提供了常用的一些命令,可以帮助开发,例如:Rgenerate, Rake, Rfind,RTview等,很方便,也很实用。 安装方法: 拷贝 autoload/rails.vim, plugin/rails.vim, 和 doc/rails.txt 到 ~/.vim 目录. ...

    Rails.Angular.Postgres.and.Bootstrap.2nd.Edition

    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 应用程序集成.zip

    webpack-rails, 将 web pack与你的Ruby on Rails 应用程序集成 不再维护webpack-rails 不再被维护。... web pack-railsweb pack 为你提供了将 web pack集成到现有的Ruby on Rails 应用程序中的工具。它很乐

    rails_apps_composer, 一个 gem,为 Rails 启动应用程序创建 Rails 应用程序模板.zip

    rails_apps_composer, 一个 gem,为 Rails 启动应用程序创建 Rails 应用程序模板 Rails 应用编辑器 Rails 应用程序编辑器 gem 安装一个 命令行 工具来从"食谱"的Collection 组装 Rails 应用程序。"你可以使用 rails_...

    rails.girls.utrecht.2015:Rails Girls Utrecht 2015 闪电演讲

    在这个“rails.girls.utrecht.2015”压缩包中,我们主要关注的是JavaScript这一标签。JavaScript是一种广泛应用于Web开发的脚本语言,它在前端开发中扮演着核心角色,用于增强用户交互、处理数据、创建动态内容等。...

    rails-exporter-源码.rar

    在 Rails 应用中,模型负责数据操作,视图负责展示,控制器则作为两者之间的桥梁,处理用户请求并协调数据展示。 二、Exporter 概念 数据导出是 web 应用中常见的需求,例如生成 CSV、Excel 或 PDF 文件供用户下载...

    SitePoint[1].Simply.Rails.2.2nd.Edition.May.2008.pdf

    10. **Rails插件**:介绍Rails社区中流行的插件,包括如何查找、安装和自定义插件,以增强应用的功能或简化开发过程。 11. **调试、测试和基准测试**:教授如何调试Rails应用,如何编写单元测试和集成测试,以及...

    Rails上的API:使用Rails构建REST APIAPIs on Rails: Building REST APIs with Rails

    在本篇内容中,我们将深入探讨如何利用Ruby on Rails(简称Rails)这一强大的Web应用程序框架来构建可伸缩且易于维护的RESTful API。Rails以其简洁优雅的语法、高效的开发速度以及良好的社区支持而闻名,这使得它...

    Ruby on Rails:Rails与JavaScript集成.docx

    Ruby on Rails:Rails与JavaScript集成.docx

    Ruby+on+Rails快速Web应用开发实战.pdf

    - **MVC架构**:文档中提到的MVC是Rails的核心架构模式,它将应用程序分为三个主要的组件:模型(Model)、视图(View)和控制器(Controller)。这种分离使得代码更加模块化,易于管理和扩展。 ### Rails应用的...

    rails.macro:允许JavaScript代码访问configroutes.rb中的名为Rails的路由

    类似于Rails的url帮助器, rails.macro为每个已定义的路由提供方法,即&lt;routeName&gt;_path和&lt;routeName&gt;_url 。 您可以从导出的Routes对象中调用它们。 基本用法 给定Rails路线my_cool_thing config / routes.rb ...

    rails.terakoya.io:Rails寺古屋

    $ cd rails.terakoya.io $ bundle install 开机 $ bundle exec middleman server 手动构建和发布 $ git pull --rebase origin master $ bundle exec middleman build $ bubdle exec middleman deploy

Global site tag (gtag.js) - Google Analytics