Rails - 将视图的 javascript 代码移动到 javascript 文件

Posted

技术标签:

【中文标题】Rails - 将视图的 javascript 代码移动到 javascript 文件【英文标题】:Rails - Move view's javascript code to javascript files 【发布时间】:2016-12-18 02:49:01 【问题描述】:

首先让我告诉你,我已经搜索过这个问题并没有找到任何答案。

我的 layouts/application.html.haml 文件中有很多 javascript

### at the end of application.html.haml file

- if @instance_variable.condition

    :javascript
        // a lot js/jQuery code

    :javascript
        // more js code that uses # @instance.vars 

    - if @another_condition.using.ruby.cody

        :javascript
            // more js code that uses # @instance.vars 

我在这段代码中使用了实例变量,这意味着这个变量只会在控制器(应用程序控制器)上声明。由于这是应用程序布局,因此这些脚本在我网站的每个页面上运行(这当然是我所需要的)。

我想要的是将所有这些代码移动到 js.erb 文件(或 .haml,如果可能的话)。首先 - 因为更容易在单独的文件中管理此代码;第二 - 因为我不想在每个 html 文件的末尾有 <script> // a lot of js code </script> 标签,我只想有一个 <script async src='link'/> 标签。

我也已经在文件的开头包含了application.coffee,但我需要在 html 文件的末尾使用这个脚本标签。

【问题讨论】:

【参考方案1】:

我不建议为此使用部分。因为,您的代码使用变量,这意味着它会根据您的变量而变化。如果将它们放入单独的 javascript 文件中,浏览器将不知道更改并使用缓存文件。一种解决方法是在文件名的末尾添加一些字符串(当 vars 更改时会更改),但是这样一来,您将失去将 javascript 移动到单独文件中的所有好处。

更好的方法是在您的 application.html.haml 中定义变量,将您的 javascript 代码移出到单独的文件中,然后只使用定义的变量。

application.html.haml

- if @instance_variable.condition
    %script(src="path/to/my/script.js")

    :javascript
        = var some_var = #@instance.vars

    %script(src="path/to/my/second_script_that_uses_var.js")

【讨论】:

感谢您的回答。但这还不是我要找的。我希望 Rails 在每次用户请求时生成一个不同的 js 文件(就像它生成不同的 HTML 文件一样)。这难道不是可能的吗? 我在以“A workaround would be to ...”开头的句子中解释了如何做到这一点,并解释了为什么你不应该 在接下来做。 但我也不想这样。您是在谈论在调用文件时添加查询吗?出于安全原因,我也不想要这些,我想要这些变量,并且这些值从 html 视图中隐藏。 无论如何,他们最终都会成为客户。所以,你真的不能谈论保护这些变量吗?还是您只是将它们用于if 检查? 不,我确实在 js 代码中使用了这些变量。例如,我不希望用户能够编辑它们并在浏览器控制台上运行这些脚本。如果我有另一个动作/视图,当被调用(需要配置路由 ofc)时会呈现一个 js 文件怎么办?这可能吗?我正在尝试对此进行测试,但出现错误。【参考方案2】:

感谢您的回答 Uzbekjon,但经过一番研究,我找到了一种方法来做我想要的 :)

在我的“layouts/application.html.haml”文件中,我添加了一个脚本标签:

### at the end of application.html.haml file

%scriptasync: 'async', src: application_scripts_path

然后我将此路径添加到路由:

get 'application_scripts' => 'controller#application_scripts', as: :application_scripts

然后我只需在我的控制器上设置此操作application_scripts并创建一个新视图 (app/views/controller/application_scrips.js.erb):

class Controller < ActionController::Base

    # 1
    protect_from_forgery except: :application_scripts

    def application_scripts

        # 2
        if condition.that.tells.me.this.request.is.valid

            # 3
            render formats: [:js] and return

        end
        render plain: ''
    end

这些步骤当然更难发现:

1 - 我必须禁用此保护,否则我会收到此错误:

ActionController::InvalidCrossOriginRequest 在 /application_scripts

安全警告:另一个网站上的嵌入标签请求了受保护的 JavaScript。如果您知道自己在做什么,请继续禁用此操作的伪造保护以允许跨域 JavaScript 嵌入。

2 - 为了确保没有其他站点可以请求此脚本文件(不是说这对我来说可能是个问题,但我更喜欢这种方式),我添加了一个条件来确保请求来自我的网站。在这种情况下,我只是检查用户是否已登录。 3 - formats: [:js] 告诉 Rails 视图不是 .html,而是一个 .js 文件 'application_scripts.js.erb'

最后,我只需将我的所有代码从 application.html.haml 文件移动到视图文件 'application_scripts.js.erb' 并将 haml 代码也转换为 erb。

<% @instance_variable.condition %>

    // a lot js/jQuery code

    // more js code that uses <%= @instance.vars %>

    <% @another_condition.using.ruby.cody %>

        // more js code that uses <%= @instance.vars %>

    <% end %>
<% end %>

【讨论】:

以上是关于Rails - 将视图的 javascript 代码移动到 javascript 文件的主要内容,如果未能解决你的问题,请参考以下文章

Ruby on Rails:将数据调用到 javascript 中的首选方法?

Rails:在 Rails 视图中使用 javascript 函数的正确语法

如何在 Rails 视图中将 Ruby 变量传递给 JavaScript 函数?

在视图中嵌入 Rails 视图

在 Rails 视图中使用通过轮询检索的数据

如何在Rails视图中将Ruby变量传递给JavaScript函数?