在rails上显示Ruby中的树结构

时间:2017-03-31 14:52:31

标签: ruby-on-rails ruby jstree

我有人帮助我在视图中显示树状结构。我已成功创建名为“Element”的单个表之间的父子关联。这些条目也以适当的方式保存。

我已为此构建代码,但它在一个级别上工作,因为我已经使用了我想要优化的循环,我希望看到代码可以获得快速解决方案。

class Element
  include Mongoid::Document
  validates :name, presence: true

  field :name, type: String
  field :description, type: String
  field :top, type: String

  has_many :media_files

  has_and_belongs_to_many :parents, :class_name => 'Element'
  has_and_belongs_to_many :childrens, :class_name => 'Element'

  def self.js_tree
    json_data = Array.new
    elements = Element.where(top: "true")
    get_inner_elements elements, json_data
   return json_data.uniq {|e| e[:id] }.to_json
  end

  def self.get_inner_elements elements, json_data
    elements.each do |element|
      single_element element, json_data
      element.childrens.each do |inner_element_one|
        single_element inner_element_one, json_data, element.id
        inner_element_one.childrens.each do |inner_element_two|
          single_element inner_element_two, json_data, inner_element_one.id
          inner_element_two.childrens.each do |inner_element_three|
            single_element inner_element_three, json_data, inner_element_two.id
            inner_element_three.childrens.each do |inner_element_four|
              single_element inner_element_four, json_data, inner_element_three.id
            end
          end
        end
      end
    end
    return json_data
  end

  def self.single_element element, json_data, parent=nil
    json_data << { 
        :id     => "#{element.id}", 
        :parent => "#{parent.nil? ? '#' : parent}",
        :a_attr=> { class: "foldor-icon" },
        :text   => "#{element.name}"
      }
      element.media_files.each do |mf|
        json_data << { 
          :id     => "file_#{element.id}_#{mf.id}",
          :parent => "#{element.id}", 
          :text   => mf.file_filename,
          :icon     => mf.icon,
        }
      end
    return json_data  
  end

end

前端:

<script type="text/javascript">
  data = $.parseJSON('<%= raw Element.js_tree %>')
  $('#container').jstree({
   'core' : {
      'data' : data
    }
  });
</script>

get_inner_elements需要优化请有人建议如何操作需要使用递归我无法应用。

Thannks

1 个答案:

答案 0 :(得分:1)

我认为你应该尝试使用递归算法。

def self.get_inner_elements(elements, json_data)
    elements.each do |element|
        if elements.children.count > 0
            single_element(element, json_data, element.parent?)
            get_inner_elements(element.children, json_data)
        else
            single_element(element, json_data, element.parent?)
        end
    end
    json_data
end

它可能没有完美优化,但它比你拥有的那棵大树更具可读性。

这里需要注意的是,不会保留相同的元素顺序,如果这不是要求之一,您可以轻松使用它,否则,您将不得不重新订购json_data您有输出