我有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
...
答案 0 :(得分:3)
你不能两次调用渲染,这是问题#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,或者根本没有选项。