【问题标题】:How can I access global javascript variables in unobtrusive javascript in a Rails app?如何在 Rails 应用程序中访问不显眼的 javascript 中的全局 javascript 变量?
【发布时间】:2014-10-05 12:49:26
【问题描述】:

我的 Rails 4 应用程序中的一个视图会加载一个简单的 javascript,以便在页面加载后创建 Ace 编辑器的实例...

$(function() {
  var editor = ace.edit("editor");
}):

在那个视图中,我有一个简单的 ajax 按钮...

<%= button_to "Set Content", {controller: :pages, action: 'set_content'}, remote: true %>

请求一些不显眼的 javascript...

editor.setValue("New content has been set");

但这不起作用。我猜这不起作用,因为editor 没有定义。由于 ajax 调用静默失败,而且我不知道如何使用与调试普通 javascript 代码相同的 Chrome 工具来调试不显眼的 javascript 代码,因此我无法验证这是实际问题,但这是我的最佳猜测。

我的印象是,如果我写var editor,那么它被声明为一个全局变量,我的不显眼的javascript应该能够访问。

我的问题是……

  1. 如何在不显眼的 javascript 代码中访问全局变量?
  2. 由于全局变量被认为是邪恶的,有没有更好的方法从我不显眼的 javascript 中访问 editor 变量?

提前感谢您的智慧!

【问题讨论】:

    标签: javascript jquery ruby-on-rails ajax


    【解决方案1】:

    当您在函数中使用 var 关键字时,该变量的范围是函数的本地变量,因此您对全局范围的假设是不正确的。要使变量成为全局变量,请在函数之外声明它:

    var editor;
    $(function(){
       editor = ace.edit('editor');
    });
    

    或者,您可以简单地引用窗口对象(它是浏览器中的“全局”对象

    $(function(){
       window.editor = ace.edit('editor');
    });
    

    关于避免使用全局变量,使用单个全局变量(通常称为“app”或“myCompany”等来提供全局可访问的命名空间是合理的。

    var app = {};
    $(function(){
      app.editor = ace.edit('editor');
    });
    

    这至少限制了新变量的范围,因此您不会错误地覆盖全局变量。然而,避免全局变量的真正答案在于应用程序的整体架构,如果不查看更多代码,就无法真正解决这个问题。一般来说,如果您编写的所有代码都在您的 jquery 就绪函数中,那么您不需要全局变量。 Angular、ember 和主干等框架为此类事物提供了比 jquery 简单使用常见的临时代码更好的结构。

    【讨论】:

      【解决方案2】:
      $(function() {
        var editor = ace.edit("editor");
      });
      

      在其回调函数的上下文中创建一个局部变量编辑器。要在其他地方访问它,您需要将其设为全局 window.editor = ace.edit("editor"),或将其添加到具有类似

      的名称空间
      window.App = {};
      App.editor = ace.edit("editor");
      

      【讨论】:

      • 你比我早 1 分钟 :P minor nitpick: 按照惯例,大写的变量名通常保留给与 New 关键字一起使用的函数。
      • @AllanNienhuis 命名空间是大写的另一种常见用法,还有构造函数和常量(通常都是大写)。
      • 我已经看到对“常量”使用所有大写字母 - 没有注意到命名空间的大写,但我可以看到这一点 - 与“常规”本地变量区分开来。干杯! :)
      • @AllanNienhuis 这不是通用的。在流行的库中,Backbone、Ember 和 React 使用它们的命名空间,而 Knockout、Angular、jQuery 和 d3 则没有。但这肯定是一个非常普遍的约定,并没有错。
      猜你喜欢
      • 2011-10-20
      • 2015-07-28
      • 1970-01-01
      • 2012-11-16
      • 2019-03-29
      • 2011-05-31
      • 1970-01-01
      • 2019-07-05
      • 2020-06-12
      相关资源
      最近更新 更多