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

Dav*_*ole 5 elixir phoenix-framework

我有一个模板,用于我的应用程序的顶部导航,top_navigation.html其中包含"登录","注册",并在登录时,"退出"链接.

<%= 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 %>
Run Code Online (Sandbox Code Playgroud)

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

有没有办法将渲染的模板作为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
Run Code Online (Sandbox Code Playgroud)

和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()
    }
  })
})
Run Code Online (Sandbox Code Playgroud)

非常感谢提前!

Chr*_*ord 4

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

|> json(%{nav: Phoenix.View.render_to_string(MyView, "nav.html", conn: conn)})
Run Code Online (Sandbox Code Playgroud)