【问题标题】:Rendering JSON in Phoenix在 Phoenix 中渲染 JSON
【发布时间】:2016-08-18 06:27:54
【问题描述】:

我使用“mix phoenix.gen.json”生成渲染 json 的代码,结果如下图:

defmodule Pghm.SightingsView do    
  use Pghm.Web, :view

  def render("sighting.json", %{sighting: sighting}) do
    %{what: sighting.what,
      lat:  sighting.lat,
      long: sighting.long}
  end

  def render("index.json", %{sightings: sightings}) do
    %{data: render_many(sightings, Pghm.SightingsView, "sighting.json")}
  end

  def render("show.json", %{sighting: sighting}) do
    %{data: render_one(sighting, Pghm.SightingsView, "sighting.json")}
  end
end

但是,当我尝试访问调用它时,我收到:无法为 Pghm.SightingsView 呈现“sighting.json”,请为 render/2 定义匹配子句或在“web/templates/sightings”处定义模板。没有为此模块编译模板。 分配:

我看过的所有地方都表明这应该有效,但我没有得到爱。

【问题讨论】:

  • 你能告诉我们被调用的控制器动作吗?

标签: elixir phoenix-framework


【解决方案1】:

我最近也开始使用 Phoenix,但可能我知道问题出在哪里。

def render("sighting.json", %{sighting: sighting}) do
  %{what: sighting.what,
    lat:  sighting.lat,
    long: sighting.long}
end

这个函数的定义说,只有你这样调用它才会起作用:

render("sighting.json", %{sighting: some_data})

但是这段代码:

%{data: render_many(sightings, Pghm.SightingsView, "sighting.json")}

将视线本身传递给渲染的第二个参数,而不是必需的 %{sighting:Sighting} 东西。所以 Elixir 找不到适合给定参数的渲染实现并引发错误。

变化

def render("sighting.json", %{sighting: sighting}) do

只是

def render("sighting.json", sighting) do

应该可以解决问题。

【讨论】:

    【解决方案2】:

    我今天遇到了这个问题,这是因为我将视图的名称复数化了,就像在 Rails 中一样。

    根据凤凰源码中的cmets(1),key是从视图名中推断出来的。

    集合是任何可枚举的结构。这个函数返回 列表中呈现的集合: render_many users, UserView, "show.html" 大致相当于:

    Enum.map(users, fn user ->
      render(UserView, "show.html", user: user)
    end)
    

    底层用户作为:user 传递给视图和模板,这是从视图名称中推断出来的。可以使用 :as 选项自定义 assigns 中的键名

    (1)https://github.com/phoenixframework/phoenix/blob/8a6beef9e13f049a8458db25b71fb70afae7673a/lib/phoenix/view.ex#L267

    所以试试这个:

    defmodule Pghm.SightingView do    
      use Pghm.Web, :view
    
      def render("sighting.json", %{sighting: sighting}) do
        %{what: sighting.what,
          lat:  sighting.lat,
          long: sighting.long}
      end
    
      def render("index.json", %{sightings: sightings}) do
        %{data: render_many(sightings, Pghm.SightingView, "sighting.json")}
      end
    
      def render("show.json", %{sighting: sighting}) do
        %{data: render_one(sighting, Pghm.SightingView, "sighting.json")}
      end
    end
    

    【讨论】:

    • 另一种解决方案(如文档中所述)是在使用 render_many/4 函数时添加 as: :sighting 作为第四个参数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多