0

我有 Vacancies 控制器,我需要将 @vacancies 传递给 json 并呈现另一个布局。以下代码不起作用(未传递 json,但我有“宽”布局)。如果我删除format.html { render layout: "wide"} } json 正确传递。如何将这两件事结合起来?

class VacanciesController < ApplicationController
respond_to :html, :json
...
    def index
      @vacancies = Vacancy.all
      respond_with(@vacancies) do |format|
       format.html { render layout: "wide"} }
       format.json { render json: @vacancies } 
      end
     end
  ...
4

1 回答 1

3

你不能调用 render 两次,这是问题 #1。您也不能对单个请求发送两个响应。

同时呈现 HTML(这意味着新的页面加载)和发送 JSON(用于 AJAX 请求,即不重新加载页面的请求)也没有任何意义。这是不可能的,但即使有可能也是毫无意义的。

如果您想告诉请求使用特定布局,可以将布局选项传递给渲染调用。但是,渲染调用不会将数据对象作为第一个参数,它会使用视图名称或仅选项哈希。因此,要正确调用它,您应该使用:

render :index, :layout => 'example'

我希望这将使您的 HTML 视图正确显示。

但是请理解,布局选项仅对 HTML 响应有用,对 JSON 响应无效。布局告诉你的渲染调用什么外部 HTML 包裹你的动作调用的视图,如果你没有指定它使用 'application.html'

为了帮助您理解另一件事:您的响应块告诉计算机如何响应不同类型的请求。它就像一个交换机。如果您使用 if/else 语句编写它,它可能如下所示:

if request_type == 'html'
  render :index, :layout => 'wide'
elsif request_type == 'json'
  render :json => @vacancies
else
  raise raise ActionController::UnknownFormat
end

因此,使用您的 respond_with 块,如果您修复了 html 渲染调用,并假设您在 localhost 上进行开发,如果您在浏览器中输入以下 URL 并按 Enter...

http://localhost:3000/vacancies

这将发出一个 HTML 格式的 GET 请求,它将加载页面layout: 'wide'但没有其他数据。如果您键入:

http://localhost:3000/vacancies.json

这将模拟 JSON 请求,您将只获得@vacancies数据的 JSON 表示形式。

我希望这可以帮助您解决问题。如果没有,请更详细地描述您要完成的工作,以便我可以帮助您了解如何做到这一点。

PS:最后一个提示:如果您想在控制器级别指定布局,您可以在layout控制器顶部调用,如下所示:

class ExampleController < ApplicationController
  layout 'awesome', :only => [:new,:edit]
  ...
end

这与任何其他过滤器一样工作,您可以传递 :only 或 :except 或根本不传递任何选项。

于 2013-02-10T01:29:55.583 回答