elixir - Phoenix:拥有相同资源的 JSON 和 HTML 表示
问题描述
我开始在教程之外将 Phoenix 用于一个小用例。到目前为止很棒,但我对以下内容有点吃惊。
我有一个资源“记录”,我想在 JSON 中的 /api/recordings 和带有模板的 /recording 访问它,结果是 HTML。
理想情况下,Ecto 表示将是唯一的,甚至控制器的一部分也会被共享?
现在我要么必须有 2 个资源 recordAPI 和 recordingHTML,要么 2 个控制器和 1 个资源。
有什么例子吗?我一直在寻找其中一个,但找不到用于同一资源的 :api 管道和 :browser 管道。
谢谢
解决方案
您可以使用凤凰accepts
插头和两种不同视图/布局的组合
# router.ex
defmodule TestExWeb.Router do
use TestExWeb, :router
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_flash
plug :protect_from_forgery
plug :put_secure_browser_headers
end
pipeline :api do
plug :accepts, ["json"]
end
scope "/", TestExWeb do
pipe_through :browser
get "/recording", PageController, :index
end
scope "/api", TestExWeb do
pipe_through :api
get "/recording", PageController, :index
end
end
如您所见,:browser
使用:accepts ["html"]
while:api
使用:accepts ["json"]
. 您可以在您的私有结构中找到conn
它并在控制器中使用它,如下所示:
defmodule TestExWeb.PageController do
use TestExWeb, :controller
def index(%{private: %{phoenix_format: format}} = conn, _params) do
data = "Hello World"
render(conn, "index.#{format}", data: data)
end
end
现在,您只需要告诉 phoenix 如何渲染您的 json,html 已经page.html.eex
在布局中处理好了,所以将以下内容添加到您的page_view.ex
defmodule TestExWeb.PageView do
use TestExWeb, :view
def render("index.json", %{data: data}) do
%{
data: data
}
end
end
此解决方案有两个缺点:
- 您在每个控制器中都需要此格式片段(也许您可以在“发送”响应后用插头绕过它)
- 您正在使用 phoenix 的内部变量
推荐阅读
- python - office365 sharepoint open binary 给出缺少架构错误
- javascript - 为什么digest 和digest('hex') 会导致不同的输出?
- javascript - 移至下一步或返回步进材料 UI 时,数据未存储
- c# - 此错误的新内容:传递到字典中的模型项的类型为“System.Collections.Generic.List`1[]
- r - 开关错误(类(数组数据),矩阵 = {:EXPR 必须是长度为 1 的向量
- git - 在通过 HTTPS 为 Google Source Repository 调用 git clone 时,有没有办法传递访问令牌
- java - Apache Netbeans 输出窗口显示的不仅仅是结果
- python - 使用正则表达式仅提取艺术家姓名
- javascript - 访问 Formik FieldArray 中的嵌套数组
- ios - 使用 UISlider 减小包含当前时间的变量的值