respond_to和respond_with如何在rails中工作?

时间:2014-07-14 22:29:57

标签: ruby-on-rails ajax respond-to

当有

def some_action
  respond_to do |format|
    format.html {}
    format.js {}
    format.json { respond_with @objects}
  end
end

似乎html行和js行自动提供/调用匹配动作名称的文件。并且html和js提供一个或另一个,而不是两者。这是对的吗?

如果你的js中有一个被调用的ajax调用,它会调用json,它会请求数据,这些需要数据来响应,对吗?我是否需要它来响应json和js,或只是一个?

如果您没有回复并省略所有类型,默认是否会回复html和js?

当我在控制器中执行respond_to而不是每个动作中的respond_to块时,使用respond_with @objects是否适用于任何参数(:thml,:js,:xml,:json等)?

替代语法:

class TheController < ApplicationController

  respond_to :html, :js, :json, only: [:some_action, :other_action]

  def some_action
    respond_with @objects
  end
end

备用语法如何工作?

如果您使用备用语法,您是否可以对不同类型的请求做出不同的响应?如果要以不同的方式响应,是否必须执行respond_to阻止而不是替代语法?这些案例中的每一个如何解决html的优雅降级问题?

3 个答案:

答案 0 :(得分:9)

  

respond_with

     

对于给定的控制器操作,respond_with根据客户端请求的mime类型生成适当的响应。

这基本上意味着您的控制器将根据请求发送相应的数据 - 例如,如果您执行了以下操作:

#app/controllers/articles_controller.rb
Class ArticlesController < ApplicationController
   def show
       @article = Article.find params[:id]
       respond_with @article
   end
end

每次发送请求时,这基本上会响应来自@article的数据。如果请求在json mime-type中,它将作为JSON对象返回;如果是HTML请求,它将返回show视图

上的HTML对象

-

  

respond_to

     

基本上允许您定制对不同mime类型的特定响应。如果发送JS请求,则可以管理JS响应等

控制器操作中的

respond_to块非常麻烦,只是对响应本身的特定更改/编辑才真正意义。

处理respond_to的一种更简单的方法是将它声明在控制器文件的顶部,基本上告诉Rails每个操作都将使用该方法中定义的选项:

#app/controllers/your_controller.rb
Class YourController < ApplicationController
   respond_to :js, :json, :html #-> the same as using respond_to block for each action
end

答案 1 :(得分:7)

请注意, Rails 4 respond_with功能已被提取到gem 'responders'https://github.com/plataformatec/responders)。

答案 2 :(得分:0)

您需要/不需要每个format.*whatever*行的情况。

通常情况下,你不需要任何一个。 Rails默认查找匹配控制器名称的视图文件夹下的操作名称的html文件(也称为模板)。

我不确定何时/为什么json和html有时会配对在一起(比如在脚手架生成的代码中)。也许json线用于turbolinks(请确认/更正此)。但是我知道当你希望每种类型的行为不同时(例如,通过js一次提供10个结果,但通过html获得更多结果),你会使用带有各种格式行的respond_to块。

在表单或链接中使用remote: true时,需要使用js格式。这是因为使用此remote:true会禁用html模板,而是查找与操作名称匹配的js文件,并执行/呈现该文件。如果你只是在js中做事,你实际上并不需要回应json线。

Bonus提示:如果您的js文件有js.erb,您可以访问您在操作中设置的实例变量(本地变量如何?请确认/更正)。这种情况很有意义,因为您的*.js.erb文件在技术上是一种视图。视图可以访问其相应的操作&#39;变量(嗯什么时候从另一个控制器渲染vies?)。因此,如果您已经可以访问js文件中的操作变量,则可以在许多情况下无需进行ajax调用或json调用。

在使用remote: true / javascript时,我实际上不确定何时需要json行。需要json数据的显式jQuery.ajax()方法调用可能会保证使用对json行的响应。