Elixir Phoenix : Controller와 View(Template)간의 데이터 전달 : assigns
Contorller에서 URI의 parameter를 받아서, 이를 HTML 내에 표현해야 하는 경우가 있습니다.
또는 사용자의 요청에 따라서 DB를 조회하고 그 결과를 HTML에 표현해야 하는 경우도 있습니다.
이와 같이 Controller 에서 Template내에 표현되어야하는 어떤 데이터를 전달할때 assigns를 사용합니다.
assigns는 controller의 conn(Plug.Conn)에 할당을 해도되며, render 함수의 3번째 파라미터로 전달해도 됩니다.
router에 두개의 URI을 다음과 같이 추가하여, 이에 대한 설명을 진행하겠습니다.
scope "/", HelloWebWeb do
pipe_through :browser
get "/", PageController, :index
get "/hello" , PageController, :hello
get "/now" , PageController, :now
get "/calc" , PageController, :calc
get "/response1" , PageController, :response1
get "/response2" , PageController, :response2
get "/greeting1" , PageController, :greeting1
get "/greeting2" , PageController, :greeting2
end
Controller의 구현은 다음과 같습니다.
def greeting1(conn, %{"name" => name}) do
render(conn, "greeting.html",[name: name])
end
def greeting2(conn, %{"name" => name}) do
conn
|> assign(:name, name)
|> render("greeting.html")
end
첫번째 구현 함수, greeting1 은 render함수의 3번째 인자인 keyword list를 이용하여 URI 입력 파라이터 name을 전달하였습니다.
3번째 인자는 Keyword List 이므로, 여러개의 파라미터 전달이 가능하며 Elixir에서는 함수 호출의 마지막 파라미터가 Keyword list 인경우에는 "[]" 를 생략할 수 있으므로,
render(conn, "greeting.html", name: name)
와 같이 할 수도 있습니다.
두번째, 함수의 구현은 assign(Plug.Conn, key, value) 함수 https://hexdocs.pm/plug/1.8.1/Plug.Conn.html#assign/3을 이용하여,
Plug.Conn의 assigns Map에 파라미터를 전달하였습니다.
위의 두 함수는 완전히 동일한 결과를 만듭니다.
이렇게 전달된, 데이터는 template에서 다음과 같이 사용할 수 있습니다.
-------------- file : greeting.html.eex ------------
<section class="phx-hero">
<h1>안녕하세요, <%= @name %> 님!</h1>
</section>
--------------------------------------------------
위 controller 에서 전달한 데이터의 key 인 :name 을 template 에서는 '@'를 붙여 사용하면 됩니다.
render 함수 호출를 호출 할 경우, 사용자 전달한 데이터 이외에 기본적으로 template에서는
@conn 을 이용하여, controller의 conn(Plug.Conn) 을 참조할 수도 있습니다.
이과 같은 방식으로, Controller에서는 View Template에서 표현될 데이터를 전달할 수 있습니다.