如何让Rails.ajax方法在Rails项目所有页面中正常调用
Rails 6使用SweetAlert2发起DELETE请求时Rails.ajax未定义问题解决
问题场景
我正在Rails 6.1.3.1环境下使用sweet alert 2库发起HTTP DELETE请求,最初编写的如下代码可正常运行:
<button script=' Swal.fire( "Good job!", "You clicked the button!", "success" ) location.pathname = "<%= home_about_path %>"; // 跳转到关于页 '>TEST</button>
但上述方式仅支持GET请求,要实现DELETE等其他类型的请求需要使用AJAX。我查到可以用Rails.ajax(...)执行异步JavaScript,但添加如下代码后出现报错:friends:22 Uncaught (in promise) ReferenceError: Rails is not defined。
// 路径:project-name/app/views/friends/index.html.erb Swal.fire( "Good job!", "You clicked the button!", "success" ) Rails.ajax({ type: "GET", url: "<%= home_about_path %>", success: function(response){ alert("成功跳转到关于页") }, error: function(response){ alert("出错:" + response) } });
我在声明Rails对象的project-name/app/javascript/packs/application.js文件中测试Rails.ajax(..),以下代码仅为测试用途会导致无限循环,但可正常运行,页面会反复跳转到关于页:
import Rails from "@rails/ujs" import Turbolinks from "turbolinks" import * as ActiveStorage from "@rails/activestorage" import "channels" Rails.start() Turbolinks.start() ActiveStorage.start() Rails.ajax({ type: 'GET', url: '/home/about', success: function(response){ location.pathname = "/home/about" }, error: function(response){ alert('删除出错' + response) } });
我遇到的问题是:为什么Rails.ajax()仅在声明它的文件中生效,在特定页面/控制器视图中就无法使用?如何配置才能让Rails变量在全局生效?
问题原因
@rails/ujs默认以ES模块的形式导入,模块内部的变量默认属于模块私有作用域,仅会在导入它的application.js文件内部生效,不会自动暴露到浏览器的全局window对象上,因此视图层的内联JavaScript代码无法直接访问到Rails变量。
解决方案
第一步:修改application.js文件
在application.js末尾添加一行代码,将Rails对象挂载到全局window对象上:
import Rails from "@rails/ujs" import Turbolinks from "turbolinks" import * as ActiveStorage from "@rails/activestorage" import "channels" Rails.start() Turbolinks.start() ActiveStorage.start() // 新增这行代码,将Rails暴露到全局 window.Rails = Rails;
第二步:修改视图代码
调整index.html.erb中的代码即可正常调用Rails.ajax发起DELETE请求:
Swal.fire( "Good job!", "You clicked the button!", "success" ) var redirect = '<%= friends_path %>'; redirect += '/<%= friend.id %>'; Rails.ajax({ type: 'DELETE', url: redirect, success: function(response){ // 好友已删除 }, error: function(response){ // Ajax请求出错 alert('删除出错' + response) } });
内容的提问来源于stack exchange,提问作者programming_ritual
相关产品推荐
相关产品推荐

