phoenix学习笔记(controller)
defmodule MyAppWeb.UserController do use MyAppWeb, :controller def show(conn, %{"id" => id}) do user = Repo.get(User, id) render(conn, "show.html", user: user) end end
- 简介
router.ex 的下一步骤。 show 是一个action,作用是接收connection和请求参数。connection是一个Plug.Conn
结构体。
- Plug pipeline
controllers 有自己的pipeline:plug。
defmodule MyAppWeb.UserController do use MyAppWeb, :controller plug :authenticate, usernames: ["jose", "eric", "sonny"] def show(conn, params) do # authenticated users only end defp authenticate(conn, options) do if get_session(conn, :username) in options[:usernames] do conn else conn |> redirect(to: "/") |> halt() end end end
如上面代码中,:authenticate plug会在action执行之前被调用。如果plug叫做 Plug.Conn.halt/1,它将会halt pipeline,action将不会被调用。
- Guards
plug :authenticate, [usernames: ["jose", "eric", "sonny"]] when action in [:show, :edit] plug :authenticate, [usernames: ["admin"]] when not action in [:index]
第一个plug 仅当action是show或者edit时执行
第二个plug,只要action不是index就执行。
- Action的参数问题
action都有两个参数,第一个是conn,这个是默认参数。是一个结构体,包含和request相关的一些东西。第二个参数是params,如果不进行参数传递,就需要加下划线_params
- Flash Messages
Phoenix.controller 主要有两个functions和flash message相关:1.put_flash 2. get_flash。
defmodule HelloWeb.PageController do ... def index(conn, _params) do conn |> put_flash(:info, "Welcome to Phoenix, from flash info!") |> put_flash(:error, "Let's pretend we have an error.") |> render("index.html") end end
put_flash: 设置key value pair。显示这个key value pair用get_flash.
<p class="alert alert-info" role="alert"><%= get_flash(@conn, :info) %></p> <p class="alert alert-danger" role="alert"><%= get_flash(@conn, :error) %></p>
get_flash的第一个参数是@conn。
- Rendering
- 文本:用text function
def show(conn, %{"id" => id}) do text(conn, "Showing id #{id}") end
2.json串:用json function,如{"id": "15"}
def show(conn, %{"id" => id}) do json(conn, %{id: id}) end
3. html:用html function
这三个都不需要Phoenix view或者相应的tmplate。json function 是用于writing api的。
4. render:render Phoenix.view 里面的function
defmodule HelloWeb.HelloController do use HelloWeb, :controller def show(conn, %{"messenger" => messenger}) do render(conn, "show.html", messenger: messenger) end end
例如:上面的HelloController
需要 HelloView
, 同时 HelloView 要求目录
the lib/hello_web/templates/hello
存在, 这个目录必须包含show.html.eex
模板.
可以用assign来传递字典,如message
def index(conn, _params) do conn |> assign(:message, "Welcome Back!") |> render("index.html") end
我们可以在index.html.eex模板里获得这个message,用<%= @message %>
.
5.直接发送response
def index(conn, _params) do conn |> send_resp(201, "") end
6. assigning layout
注:Layouts 是template的一个子集。Phoenix在创建app时,会自动创建app.html.eex, 这个layout,是所有templates默认都会render的。put_layout function可以用来选择layout。第一个参数是conn,第二个参数是我们想要render的layout,或者false。如果是false,表示我们不会render layout。
7. overriding rendering formats
8. 设置 content type
def index(conn, _params) do conn |> put_resp_content_type("text/xml") |> render("index.xml", content: some_xml_content) end
9. 设置http状态
def index(conn, _params) do conn |> put_status(202) |> render("index.html") end
10. Redirection 以后再看
11. Action Fallback 以后再看
12. Halting the Plug Pipeline 以后再看