Rails - 如何确保已在 js.erb 中呈现部分内容

Posted

技术标签:

【中文标题】Rails - 如何确保已在 js.erb 中呈现部分内容【英文标题】:Rails - how do I make sure a partial has been rendered in a js.erb 【发布时间】:2014-01-13 09:06:24 【问题描述】:

我正在尝试将 JS 函数绑定到文本字段(“文本”类型的输入)。使用 JQuery 2.0.2 和 Rails 3.1 我在位于 assets/javascripts.js.coffee 文件中执行此操作:

window.test_questions = 
window.test_questions.bind_input = ->
  $('#question_content').on 'input', ->
    // do something

然后在位于views\TheRightController 文件夹中的.js.erb 中运行:

$('#new_question').html('<%= escape_javascript(render("new_question_form")) %>');   
test_questions.bind_input();

#question_content 在部分渲染之前不存在于页面上。我担心bind_input()会在渲染完成之前运行,找不到#question_content并没有绑定任何东西。

我不是 100% 这是一个问题(我的代码目前正在运行),但我担心如果我在其他地方使用“更重”的渲染它会中断。

我的担心是徒劳的吗? 有什么方法可以确保渲染完成没有错误,然后才执行下一行。

【问题讨论】:

【参考方案1】:

这里有两个步骤。

首先执行 Ruby 脚本并将其转换为纯 html/javascript 文件。这是由服务器在将页面提供给客户端之前完成的。在这一步,你所有的&lt;%= %&gt;都会被执行。所以不用担心JavaScript会在Railsrender之前执行。

然后客户端接收页面并开始渲染它并执行javascript。如果你在bind_input 之前调用$('#new_question').html,同样不用担心,它会同步执行,你的选择器#question_content 会起作用。但是,如果您在 DOM 完全加载之前运行 $('#new_question'),则另一个选择器可能会中断。为防止这种情况,请使用 JQuery 的$(document).ready()

【讨论】:

快速跟进,$(document).ready() 在呈现新部分的异步 ajax 调用后是否再次触发?我以为它只在页面第一次加载时运行。 不,传递给ready() 的处理程序在正常情况下只会执行一次(例如,您没有包含多个 jquery 或其他奇怪的东西)。处理 ajax 调用解决后发生的事情的最佳方法是使用 .done() api.jquery.com/deferred.done 谢谢,这很有帮助。

以上是关于Rails - 如何确保已在 js.erb 中呈现部分内容的主要内容,如果未能解决你的问题,请参考以下文章

Rails '.js.erb' 不呈现部分

Rails Ajax:.js.erb 呈现为文本,而不是 JS

Rails js.erb 不呈现部分文件但得到呈现的响应文件

Rails3 使用 text/html 内容类型而不是 text/javascript 呈现 js.erb 模板

Rails 6:Ajax 不接受 js.erb 中的渲染

如何在 Rails ERB 文件的渲染部分 url 中访问 java 脚本变量?