Phoenix에서 render()를 쓰는 곳에 따라 쓰는 방법이 다르나요?

fukuoka.ex 대표의 piacere입니다
방문해 주셔서 감사합니다

Phoenix에서 render()를 사용하면 쓰는 곳에 따라 쓰는 방법이 다르다는 것을 조금 해설해 두겠습니다.

"Phoenix"은 Elixir 웹 프레임 워크입니다.

내용이 재미 있거나 도움이되면 "좋아요"잘 부탁드립니다

컨트롤러와 .eex에서 render()를 쓰는 방법이 다릅니다?



컨트롤러(일반 페이지, LiveView 모두)에서는 아래와 같이 render()를 사용합니다.

lib/sample_web/controllers/page_controller.ex
defmodule SampleWeb.PageController do
    use SampleWeb, :controller

    def index(conn, params ) do
        render( conn, page, params: params )
    end
end

한편, .eex 파일내(layout.html.eex도 포함한다)로, 다른 .html.eex 파일을 읽어들일 경우에 사용하는 render()에서는, 이하와 같이, 제1 인수가 conn가 아닙니다

lib/sample_web/templates/page/index.html.eex
<article>
    <section>
        <%= render( @view_module, "header.html", params: @params ) %>
    </section>
</article>

컨트롤러에서 사용하는 render()의 첫 번째 인수를 살펴보십시오.



먼저 컨트롤러에서 사용하는 render()의 첫 번째 인수를 살펴 보겠습니다.

아래와 같이 IO.inspect()에 의한 디버그 코드를 추가해, 브라우저 표시를 실시해, 콘솔을 확인합니다

또한, 브라우저 표시시, http://localhost:4000/?param_a=123&param_b=xyz와 파라미터를 붙여 둡니다

lib/sample_web/controllers/page_controller.ex
defmodule SampleWeb.PageController do
    use SampleWeb, :controller

    def index(conn, params ) do

IO.puts "=============================="
IO.inspect conn
IO.puts "=============================="

        render( conn, page, params: params )
    end
end

이 디버깅을 통해 첫 번째 인수가 '%Plug.Conn'임을 알 수 있습니다.
iex> [info] GET /
iex> [debug] Processing with SampleWeb.PageController.index/2
  Parameters: %{"param_a" => "123", "param_b" => "xyz"}
  Pipelines: [:browser]
iex> ==============================
iex> %Plug.Conn{
  adapter: {Plug.Cowboy.Conn, :...},
  assigns: %{},
  before_send: [#Function<2.67953897/1 in Phoenix.Controller.fetch_flash/2>,
   #Function<0.58261320/1 in Plug.Session.before_send/2>,
   #Function<1.1812729/1 in Plug.Logger.call/2>,
   #Function<0.102641852/1 in Phoenix.LiveReloader.before_send_inject_reloader/2>],
  body_params: %{},
  cookies: %{},
  halted: false,
  host: "localhost",
  method: "GET",
  owner: #PID<0.32698.1>,
   params: %{"param_a" => "123", "param_b" => "xyz"},
  path_info: [],
  path_params: %{},
  port: 4000,
  private: %{
    SampleWeb.Router => {[], %{}},
    :phoenix_action => :index,
    :phoenix_controller => SampleWeb.PageController,
    :phoenix_endpoint => SampleWeb.Endpoint,
    :phoenix_flash => %{},
    :phoenix_format => "html",
    :phoenix_layout => {SampleWeb.LayoutView, :app},
    :phoenix_pipelines => [:browser],
    :phoenix_router => SampleWeb.Router,
    :phoenix_view => SampleWeb.PageView,
    :plug_session => %{},
    :plug_session_fetch => :done
  },
  query_params: %{"param_a" => "123", "param_b" => "xyz"},
  query_string: "param_a=123&param_b=xyz",
  remote_ip: {127, 0, 0, 1},
  req_cookies: %{},
  req_headers: [
    {"accept",
     "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"},
    {"accept-encoding", "gzip, deflate"},
    …
  ],
  request_path: "/",
  resp_body: nil,
  resp_cookies: %{},
  resp_headers: [
    {"cache-control", "max-age=0, private, must-revalidate"},
    {"x-request-id", "FZvM6ESlOHrlYv4AAv2j"},
    {"x-frame-options", "SAMEORIGIN"},
    …
  ],
  scheme: :http,
  script_name: [],
  secret_key_base: :...,
  state: :unset,
  status: nil
}
iex> ==============================

.eex에서 사용하는 render()의 첫 번째 인수는 "페이지 표시에 사용하는 View 모듈"



다음으로 .eex로 지정한 첫 번째 인수를 IO.inspect()에서 살펴 보겠습니다.

lib/sample_web/templates/page/index.html.eex
<%
IO.puts "------------------------------"
IO.inspect @view_module
IO.puts "------------------------------"
%><article>
    <section>
        <%= render( @view_module, "header.html", params: @params ) %>
    </section>
</article>

이 디버그에서 첫 번째 인수가 'SampleWeb.PageView'임을 확인할 수 있습니다.
iex> [info] GET /
iex> [debug] Processing with SampleWeb.PageController.index/2
  Parameters: %{"param_a" => "123", "param_b" => "xyz"}
  Pipelines: [:browser]
iex> ------------------------------
iex> SampleWeb.PageView
iex> ------------------------------

재료 격차



실은, 인수의 수가 같고, 다른 2개의 render()가, 정의되고 있는 것입니다 (혼란스럽다…)

두 render()에 대한 참조를 살펴 보겠습니다.

컨트롤러에서 사용되는 render()는 "Phoenix.Controller"의 함수



htps : // 에 x도 cs. pm/p 쪽에 x/P 쪽에 x. 곤 t 롯 r. html # 렌데 r/3


.eex에서 사용되는 render()는 "Phoenix.View"의 함수



htps : // 에 x도 cs. pm/p 쪽에 x/P 쪽에 x.ゔぃえ. html # 렌데 r/3


왜 이런 번거로운 사양이 되어 있는 거야?



render()는 본래 뷰측에서의 정의가 MVC적인 책무입니다.

그러나 render()는 컨트롤러 내에서 자주 호출되기 때문에 편의성을 높이는 것을 목적으로 컨트롤러 측의 함수로도 구현되고 있다.

덧붙여서, 컨트롤러 및 뷰 모듈 이름 열 에서도 조금 해설하고 있습니다만, 컨트롤러의 모듈명을 기준으로, 자동적으로 뷰의 모듈명을 특정하는 것이 가능하기 때문에, 이러한 구현이 실현되고 있을까요

p.s.「좋아요」 잘 부탁드립니다



페이지 왼쪽 상단의 또는 을 클릭해 주셔서 감사합니다
여기의 숫자가 늘어나면, 작가로서는 「우케하고 있다」라는 감각을 얻을 수 있어 연재를 더욱 진화시켜 나가는 동기 부여가 되기 때문에, 보다 Elixir 재료를 보고 싶다고 하는 당신, 저희와 함께 북돋워 제발!

좋은 웹페이지 즐겨찾기