【问题标题】:Rails 3: How to send Javascript code from Controller?Rails 3:如何从控制器发送 Javascript 代码?
【发布时间】:2011-07-25 05:46:06
【问题描述】:

当通过Ajax调用MyControllerfoo方法时,可能会返回如下Javascript代码:

class MyController < ApplicationController
  def foo
    render :js => "alert('Hello');"
  end
end

foo被正常调用(不是通过Ajax)时,是否可以做类似返回Javascript代码的事情?我想做这样的事情:

class Job < ApplicationController
  def edit
    if user_type == 'demo'
      [Here I would like to display a Javascript alert saying that 
       the job cannot be edited in demo mode. How would you do this?]
    else
      @job = Job.find(params[:id])
    end
  end
end

【问题讨论】:

  • 你违背了 Rails 和 HTTP 的标准用法

标签: javascript ruby-on-rails ruby-on-rails-3


【解决方案1】:

简短的回答是:你不能。

当你为 :js 渲染时,调用代码是一个 javascript 框架,它知道它请求了 js,并将执行返回的代码以使其在异步调用执行它的 onSuccess 操作时生效。

默认渲染时,调用代码是浏览器,它期望html它不会执行纯js。

您可以做的是让您的视图返回带有一些 javascript 的 html,并定义一个 window.onload() 处理程序以使其显示警报。但是您仍然必须返回 html(如果您不想显示数据,请使用特定参数将其重定向到上一个视图模板,以便该视图具有事件处理程序) (https://stackoverflow.com/questions/1033398/execute-javascript-when-page-has-fully-loaded)

您还可以更改调用编辑操作的事件处理程序以在操作执行之前显示警报。为了防止用户禁用 js 并克服警报,您仍然需要检查 user_type 并且可能只是重定向到上一页。

【讨论】:

  • 据我了解,他的请求格式是 not :js。这是html。在这种情况下 :update 对他来说没用,因为我认为他不能渲染 :update 格式 :html,因此我的回答 ...
  • 哦,我明白了。我错过了这个问题的主要思想。 +1。他不能:)
【解决方案2】:

我建议您保持控制器清洁并将任何 JavaScript 代码放在 rjs 模板中:

控制器

class MyController < ApplicationController
   def edit
      render do |page|
        page.html {}
        page.js {}
      end
   end
 end

edit.js.erb

alert("hello");

每当/my/edit/1.js 被调用(通过:edit_my_path(1, :format =&gt; :js))时,edit.js.erb 都会呈现并显示警报。

每当/my/edit/1.js 被调用(通过:edit_my_path(1))时,edit.html.erb 将呈现为显示正常的 html。

如果您需要检查请求是否为 ajax(因此不仅仅是普通的 .js 调用),您可以在控制器中执行以下操作:request.xhr?

希望有帮助!

【讨论】:

  • @jean 双向工作不是吗。
  • 根据他的需要,它总是会调用普通的html(他说:不是xhr),因此无论user_type是否为demo,它都会显示普通的html。他可能会在“显示”模板页面中使用条件检查并使用 js 格式进行 user_type 演示,但这从您的回答中不清楚...
  • 我可能读错了整个问题。即便如此,如果他在模板中使用条件检查,它几乎是可利用的。
【解决方案3】:

当请求 js 格式时,您可以简单地将 javascript 呈现为文本

class MyController < ApplicationController
   def update
      respond_to do |format|
        format.html {}
        format.js { render text: 'alert();' }
      end
   end
 end

【讨论】:

  • 这似乎给出了一个 ActionView::MissingTemplate: Missing template resource_name/alert();
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-01
相关资源
最近更新 更多