Phoenix Framework:在JSON响应中发送呈现的模板

时间:2015-10-11 02:01:46

标签: elixir phoenix-framework

我的应用程序顶部导航模板位于top_navigation.html,其中包含"登录","注册"以及登录后,& #34;退出"链接。

<%= if logged_in?(@conn) do %>
  <li><%= link "Sign out", to: session_path(@conn, :delete), method: :delete %></li>
<% else %>
  <li><a href="#" class="js-register" data-toggle="modal" data-target=".js-register-modal">Sign up</a></li>
  <li><a href="#" class="js-login"    data-toggle="modal" data-target=".js-login-modal"   >Sign in</a></li>
<% end %>

我通过AJAX登录用户,但是一旦他们重新登录,我想用新渲染的模板换出顶部导航(显示&#34;退出&#34;链接),在登录响应中传回客户端。

有没有办法将呈现的模板作为JSON响应的一部分发送?

有些事情:

defmodule MyApp.SessionController do
  use MyApp.Web, :controller

  def create(conn, %{"user" => user_params}) do
    case MyApp.Session.login(user_params, MyApp.Repo) do
      {:ok, user} ->
        conn
        |> put_session(:current_user, user.id)
        |> json %{ top_navigation: render("top_navigation.html") }
                                   # ^^^^ this doesn't work ^^^^
      :error ->
        conn
        |> put_status(404)
        |> json %{ message: "Unable to sign in." }
    end
  end

  def delete(conn, _) do
    conn
    |> delete_session(:current_user)
    |> put_flash(:info, "Signed out.")
    |> redirect(to: "/")
  end
end

和Javascript:

$(".js-login").on("click", e => {
  e.preventDefault()
  $(".js-login-alert").hide()
})
$("#login").on("submit", e => {
  e.preventDefault()

  let form = $("#login")
  let data = { _csrf_token: $( 'input[name="_csrf_token"]' ).val(), 
               user:        { email:    form.find('input[name="email"]'   ).val(), 
                              password: form.find('input[name="password"]').val() } }

  $.ajax({
    type: "POST",
    url: "/login",
    data: data,
    success: e => {
      $(".js-top-navigation").html(e.responseJSON["top_navigation"])
      // ^^^^^^^^^^^^^^ This is where we swap it out ^^^^^^^^^^^^^^^
      $(".js-login-modal").modal("toggle")
    },
    error: e => {
      let alert = $(".js-login-alert")
      alert.text(e.responseJSON["message"])
      alert.show()
    }
  })
})

提前非常感谢!

1 个答案:

答案 0 :(得分:4)

确实是的! Phoenix模板只是其视图模块上的功能。因此,您可以通过调用函数来呈现模板:

|> json(%{nav: Phoenix.View.render_to_string(MyView, "nav.html", conn: conn)})