2017-03-31 70 views
1

我有人帮我看看树状结构。我已成功创建了名为“元素”的单个表之间的父子关联。此外,条目以适当的方式保存。在rails上显示树状结构

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

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

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

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输出