【问题标题】:How can I render a child layout inside a parent one?如何在父布局中渲染子布局?
【发布时间】:2016-09-17 04:24:21
【问题描述】:

我有一个基本的应用程序布局:

#layouts/base.html.eex
<body>
  <div id="base_layout.html">
  <!-- some content -->
    <%= render(@view_module, @view_template, assigns) %>
  <!-- some content -->
  </div>
</body>

我还有 20 种其他不同的布局。我想从base.html.eex 继承所有这些。我怎样才能做到这一点?我试过这个:

#layouts/child_layout5.html.eex
<div id="child_layout5.html">
  <!-- some content -->
  <%= render(@view_module, @view_template, Map.put(assigns, :layout, {MyApp.LayoutView, "base.html"})) %>
</div>

但这只是将基本布局呈现在 &lt;div id="child_layout5.html"&gt; 中。

而我希望反之亦然:在base.html 中渲染child_layoutXX.html.eex 的内容,来自child_layoutXX.html.eex

请注意,base.html 不知道它的子 child_layoutXX.html.eex,有多少,如果有的话,它们的名字是什么,也就是说,base.html 不能通过它的显式渲染它的任何子名字。

到目前为止,https://hexdocs.pm/phoenix/Phoenix.View.html#render/3 函数还没有帮助到我。

【问题讨论】:

    标签: elixir phoenix-framework


    【解决方案1】:

    这是传递子布局以在render 的分配映射中使用并让base 布局处理使用它的一种方法。您可以为每个操作传递不同的 child_layout 值。这样base 布局就没有任何硬编码的子布局。

    # controllers/page_controller.ex
    defmodule MyApp.PageController do
      use MyApp.Web, :controller
    
      def index(conn, _params) do
        conn
        |> put_layout("base.html")
        |> render("index.html", child_layout: "child_layout5.html")
      end
    end
    
    # templates/layout/base.html.eex
    <body>
      <div id="base_layout.html">
        <%= render(@view_module, @view_template, Map.put(assigns, :layout, {MyApp.LayoutView, @child_layout})) %>
      </div>
    </body>
    
    # templates/layout/child_layout5.html.eex
    <div id="child_layout5.html">
      <%= render(@view_module, @view_template, assigns) %>
    </div>
    
    # templates/page/index.html.eex
    <!-- index.html -->
    

    输出:

    <body>
      <div id="base_layout.html">
    <div id="child_layout5.html">
    <!-- index.html -->
    </div>
      </div>
    </body>
    

    编辑:要使base 模板在child_layout 未通过时也可以工作,您可以这样做:

    <body>
      <div id="base_layout.html">
        <%= render(@view_module, @view_template, if(assigns[:child_layout], do: Map.put(assigns, :layout, {MyApp.LayoutView, @child_layout}), else: assigns)) %>
      </div>
    </body>
    

    【讨论】:

    • 好的,但是如何使参数@child_layout 不是强制性的?也就是说,base.html 只有在传递了参数@child_layout 时才会呈现子布局。
    • “其他方式”是什么意思?
    • 正如您所说的“这是一种方式......”,还有另一种方式吗?
    • 啊。我的意思是必须有其他人可以想出的其他方法。我现在想不出更好的了。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-15
    • 1970-01-01
    • 2018-10-21
    • 1970-01-01
    相关资源
    最近更新 更多