【问题标题】:Representing hierarchical data with jstree用 jstree 表示分层数据
【发布时间】:2013-05-27 19:18:34
【问题描述】:

我无法在 Ruby on Rails 中表示分层数据,使用 jsTree 在“树文件夹结构”中可视化数据。为了使用示例数据测试插件,我遵循了这个教程:http://beginrails.blogspot.ca/2012/03/jstree-introduction.html

我正在编写的应用程序是一个非常基本的“技能清单”,具有页面(技能类型)和用户(具有技能的人)模型。页面是分层的,这意味着一个页面可以是多个页面的“父级”,也可以是多个其他页面的父级,依此类推。当“页面”不再有子级时,该页面将包含“用户”。使用示例数据,应用程序应产生如下结果:

http://i.imgur.com/O3na3Ws.png

每个页面都有一个parent_id 字段,并且所有页面都是独立的(意味着它们都包含在Page.all 中)。如果parent_id 字段为nil,则页面将仅包含用户。每个页面还有一个links 数组,其中存储了子页面的ID。这两个字段是数据层次结构的基础。我的问题是:我如何能够遍历所有页面并为 jsTree 设置正确的 HTML 以正确可视化数据?

页面模型:

# == Schema Information
#
# Table name: pages
#
#  id         :integer          not null, primary key
#  parent_id  :integer
#  name       :string(255)
#  links      :text
#  created_at :datetime         not null
#  updated_at :datetime         not null
#

class Page < ActiveRecord::Base
  include ActsAsTree
  acts_as_tree order: "name"
  attr_accessible :links, :name, :parent_id
  serialize :links
  WillPaginate.per_page = 10
end

我的 Pages 控制器的相关部分:

def index
  @pages = Page.all

  # any additional change could go here

  respond_to do |format|
    format.html # index.html.erb
    format.json { render json: @pages }
  end
end

应用程序的“索引”视图(这是 jsTree 可视化所在的位置:

<div id="treeview">
    <ul>
        <!-- jsTree logic and looping through data goes here -->
    </ul>
</div>

我是一名初学者 Rails 程序员,所以任何建设性的批评都将不胜感激。

【问题讨论】:

    标签: ruby-on-rails jstree


    【解决方案1】:

    嗯,你要求建设性的批评,所以:

    您的树定义非常不寻常。通常 parent_id 指向父级,因此没有 parent_id 的页面是根元素,没有子级的页面(意味着没有其他页面以该页面为父级)是叶子。

    acts_as_tree 的工作方式也是如此。

    接下来,您必须将树构建为 JSON 对象。这意味着,您需要递归地构造节点。每个节点都由名称和子节点组成。

    子页面要么是子页面,要么是关联的用户。

    这种树结构最好在页面模型中完成:

    class Page < ActiveRecord::Base
      include ActsAsTree
      attr_accessible :name, :parent_id
    
      acts_as_tree order: 'name'
      has_many :users
    
      def node
        {data: name, children: leaves}
      end
    
      def leaves
        if children.any?
          children.map{|child| child.node}
        else
          users.map{|user| {data: user.name}}
        end
      end
    end
    
    
    class User < ActiveRecord::Base
      attr_accessible :name, :page_id
      belongs_to :page
    end
    

    为了构建您的测试树,我创建了一些页面和用户:

    p1=Page.create name:'Laundry'
    p2==Page.create name:'Java Programming'
    p3==p2.children.create name:'Game Development'
    p4==p2.children.create name:'Console Applications'
    
    p1.users.create name: 'Bob Smith'
    p1.users.create name: 'Chuck Norris'
    p3.users.create name:'Nuck Chorris'
    p4.users.create name:'Sob Bmith'
    

    现在要构建您的 JSON 树,您需要所有根页面及其树:

    Page.roots.map{|r| r.node}
    => [{:data=>"Java Programming", :children=>[{:data=>"Console Applications", :children=>[{:data=>"Sob Bmith"}]}, {:data=>"Game Development", :children=>[{:data=>"Nuck Chorris"}]}]}, {:data=>"Laundry", :children=>[{:data=>"Bob Smith"}, {:data=>"Chuck Norris"}]}]
    

    所以你的控制器看起来像:

    class PagesController < ApplicationController
      def index
        respond_to do |format|
          format.html
          format.json { render json: Page.roots.map{|r| r.node}}
        end
      end
    end
    

    我把它留给你,让 jsTree 收集 JSON-tree。

    【讨论】:

    • 非常感谢!这似乎是一种非常有效的方法!
    • 另一个问题:使用这种结构,我怎样才能将同一个用户添加到多个页面?
    • 那么你需要在页面和用户之间建立has_and_belongs_to_may 关系。这是使用连接表pages_users。见Rails Guides
    • 很抱歉再次打扰您,但是我已经在两个模型之间建立了这种关系,并且我已经创建了连接表,但是我实际上如何将已经创建的用户对象关联到多个页面对象?如果这不可能,我如何实例化一个已经有页面关联的用户对象?
    • 这有点太长了,无法在评论中回答。你能在一个新问题中问它吗?
    猜你喜欢
    • 1970-01-01
    • 2010-11-03
    • 1970-01-01
    • 1970-01-01
    • 2014-04-23
    • 1970-01-01
    • 1970-01-01
    • 2015-10-11
    • 2012-12-26
    相关资源
    最近更新 更多