.erb模板不支持递归函数吗?

时间:2018-08-01 22:01:07

标签: ruby-on-rails ruby sinatra erb

好吧,基本上我有这样的东西:

someView.erb

 <ul>
    <% @objects.each do |object| %>
      <%= printAllChildObjects(object) %>
    <% end %>
 </ul>

app.rb

def printAllChildObjects(object)
   "<li>#{object.attributes['name']}</li>"
    if object.children.first.name == "Error"
      break
    else 
      object.elements.first.each do |innerObject| 
         printAllChildObjects(innerObject)
      end
    end
end

TL:DR;我正在使用REXML(Ruby内置的XML解析器,由于某些可笑的公司原因而无法使用Nokogiri)来解析一些XML文件。该XML文件的节点中可能嵌套有子节点,也可能没有子节点,并且子节点的数量不尽相同。我通过使用puts语句并观察终端来尝试了递归函数,该函数可以按预期工作。

但是,当我尝试合并上述视图文件时,我得到的是带有三个点的空框,即[ ... ],其中应打印每个对象。疯狂的事情是,盒子的数量与对象的数量匹配,并且使用Chrome Dev Tools检查html后,您可以看到ENTIRE对象节点,而不仅仅是object.attributes['name'](即节点中的name属性) 。

此外,当我删除递归调用并仅将"<li>#{object.attributes['name']}</li>"部分保留在函数中时,HTML再次起作用!因此,我相当确定递归会破坏HTML呈现。有某种解决方法吗?我将不胜感激。

哦,我使用的是Sinatra,而不是Rails。

2 个答案:

答案 0 :(得分:0)

尝试类似的东西:

<ul>
  <% @objects.each do |object| %>
    <% print_children_for(object).flatten.each |li_tag| %>
     <%= li_tag %>
    <% end %>
  <% end %>
</ul>

def print_children_for(object, parent = nil)
  mark_up = []
  mark_up << parent.nil? ? "<li>#{object.attributes['name']}</li>" : parent

  return mark_up if object.children.first.name == "Error"
  object.elements.first.each do |innerObject| 
     print_children_for(innerObject, markup)
  end
end

需要做一些调整(在某些地方保护nil值),我正在不加检查的情况下即时进行此操作,但也许这样可以帮助您。

答案 1 :(得分:0)

遵循建议将其追加到某个HTML缓冲区并返回显式函数的建议,以下代码解决了我的问题:

def printAllChildObjects(refObject, html)
  html << "<li>#{refObject.attributes['name']}</li>"

  if refObject.children.first.name == "Error"
     break
  else
     refObject.elements.first.each do |innerObject|
         return printAllChildObjects(innerObject, html)
     end
  end

 return html
end