4

以下是在 html.erb 中完成的迭代树,它在树结构中仅达到两个级别:

      <ul>
    <li><%= root_template.id  %></li>
      <ul>
          <% for template in root_template.children  %>
              <li><%= template.id  %></li>
              <% if template.has_children? %>
                <ul>
                <% for template_child in template.children  %>
                    <li><%= template_child.id  %></li>
                <% end %>
                </ul>
              <% end %>
          <% end %>
      </ul>
  </ul>

结果: 迭代的

我想移动帮助文件中的代码并应用递归以达到所有级别:

html.erb(因此,从模板设置根):

  <% html = '' %>
  <ul>
    <li><%= root_template.id  %></li>
    <ul>
        <%= recursive_tree root_template, html %>
    </ul>
  </ul>

然后辅助方法:

  def recursive_tree(root, html)
    html << ''
    if !root.has_children?
      html << "<li>#{root.id}</li>"
      return html.html_safe
    else
      for template_child in root.children
        html << "<ul>#{recursive_tree(template_child, html)}</ul>"
      end
    end
    return html.html_safe
  end

结果:错误的递归结果

我已经花了一天的时间来弄清楚如何将正确的 html 从帮助程序发送到模板,现在即使我使用了调试器,也无法弄清楚这种递归和解决方案的问题是什么。有意见吗?

4

2 回答 2

3

以下是我上面遇到的递归问题的最终答案,它们都共享一个类似的模板调用,如下所示:

对于溶胶 1:

  <% html = '' %>
  <ul>
    <%= recursive_tree root_template, html %>
  </ul>

对于溶胶 2:

  <ul>
    <%= call_me_baby_two root_template %>
  </ul>

解决方案 1)使上述有问题的给定代码无需任何清理即可工作:

  • 解释 1)我将整个 html 代码传递给递归调用,所以这是最大的错误,现在我传递一个空白字符串并在递归调用返回到主 html 后附加它,对于更深层次的递归调用也是如此。
  • 解释 2)如果它是孩子,我没有添加根的 id,在解决上一个问题后我已经意识到这一点。

    def recursive_tree(root, html)
    html << ''
    if !root.has_children?
      html << "<li>#{root.id}</li>"
      return html.html_safe
    else
      html << "<li>#{root.id}</li>" # Explanation 2
      for template_child in root.children 
        temp_html = '' # Explanation 1
        html << "<ul>#{recursive_tree(template_child, temp_html)}</ul>"
      end
    end
    return html.html_safe
    end
    

解决方案 2)下面我还花额外的时间使 @davidrac 的伪代码工作:

  def recursive_tree_three(root)
    html=''
    if root
      html = "<li>#{root.id}</li>"
      if root.has_children?
        for template_child in root.children
          html << "<ul>"
          html << recursive_tree_three(template_child)
          html << "</ul>"
        end
      end
    end
    return html
  end

  def call_me_baby_two(root)
    recursive_tree_three(root).html_safe
  end
于 2013-01-06T23:54:46.990 回答
1

我可以在这里发现的一个问题是您使用 html_safe 的次数超出了您的需要。由于您将 html_safe 作为递归方法的一部分,因此会为更深的节点一遍又一遍地调用它。

您的实现中似乎有问题的另一件事是<li>标签没有<ul>正确包装标签,因此对于具有多个子节点的节点,这可能会得到错误的结果

也许您可以稍微不同地构造递归方法(主要是伪代码):

def recursive_tree(root)
  res = ''
  if root
    res = "<li>#{root.id}"
    # if root has children
    #   add <ul>
    #   for each of the children res << recursive_tree(child)
    #   add </ul>
    # end
    res << "</li>"
  end
  res
end

现在添加一些包装函数来创建初始列表并添加 html_safe:

wrapping_func(root)
  "<ul>#{recursive_tree(root)}</ul>".html_safe
end

顺便说一句,如果您在问题中添加您期望的结构以及 html 输出是什么,这可能会有所帮助。

于 2013-01-06T07:55:31.137 回答