如何从一组嵌套的所有记录渲染成一个真正的HTML树 [英] How to render all records from a nested set into a real html tree

查看:313
本文介绍了如何从一组嵌套的所有记录渲染成一个真正的HTML树的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的 awesome_nested_set 插件我Rails项目。我有两个模型,像这样(简体):

I'm using the awesome_nested_set plugin in my Rails project. I have two models that look like this (simplified):

class Customer < ActiveRecord::Base
  has_many :categories
end

class Category < ActiveRecord::Base
  belongs_to :customer

  # Columns in the categories table: lft, rgt and parent_id
  acts_as_nested_set :scope => :customer_id

  validates_presence_of :name
  # Further validations...
end

在数据库中的树被构建为预期。 PARENT_ID LFT 的所有值和 RGT 是正确的。该树具有多个根节点(这当然是在允许的 awesome_nested_set )。

The tree in the database is constructed as expected. All the values of parent_id, lft and rgt are correct. The tree has multiple root nodes (which is of course allowed in awesome_nested_set).

现在,我想呈现的所有类别中特定客户的类似结构的正确排序树:比如嵌套的&LT; UL&GT; 标签。这将不会太困难,但我需要它是有效的(少SQL查询越好)。

Now, I want to render all categories of a given customer in a correctly sorted tree like structure: for example nested <ul> tags. This wouldn't be too difficult but I need it to be efficient (the less sql queries the better).

更新:想通了,就可以计算出儿童人数为树中的任何节点没有进一步的SQL查询: NUMBER_OF_CHILDREN =(node.rgt - 节点.lft - 1)/ 2 。这没有解决的问题,但它可能被证明是有益的。

Update: Figured out that it is possible to calculate the number of children for any given Node in the tree without further SQL queries: number_of_children = (node.rgt - node.lft - 1)/2. This doesn't solve the problem but it may prove to be helpful.

推荐答案

这将是很好,如果嵌套组有更好的功能开箱不会吧。

It would be nice if nested sets had better features out of the box wouldn't it.

因为你已经发现了这个窍门是从平面组构建树:

The trick as you have discovered is to build the tree from a flat set:

  • 在开始一个集合中的所有节点的排序LFT
  • 的第一个节点是根将其添加为树移动到下一个节点根
  • 如果它是previous节点的子节点添加子树,向前迈进的一个节点
  • (介于prev.lft和prev.rht LFT)
  • 否则移树一个级别,重复测试
  • start with a set of all node sorted by lft
  • the first node is a root add it as the root of the tree move to next node
  • if it is a child of the previous node (lft between prev.lft and prev.rht) add a child to the tree and move forward one node
  • otherwise move up the tree one level and repeat test

见下图:

def tree_from_set(set) #set must be in order
  buf = START_TAG(set[0])
  stack = []
  stack.push set[0]
  set[1..-1].each do |node|
    if stack.last.lft < node.lft < stack.last.rgt
      if node.leaf? #(node.rgt - node.lft == 1)
        buf << NODE_TAG(node)
      else
        buf << START_TAG(node)
        stack.push(node)
      end
    else#
      buf << END_TAG
      stack.pop
      retry
    end
  end
  buf <<END_TAG
end

def START_TAG(node) #for example
  "<li><p>#{node.name}</p><ul>"
end

def NODE_TAG(node)
  "<li><p>#{node.name}</p></li>"
end

def END_TAG
  "</li></ul>"
end

这篇关于如何从一组嵌套的所有记录渲染成一个真正的HTML树的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆