如何将 rails 视图的 javascript 代码放入 assets/javascript 文件夹?

How to put javascript code for rails view to assets/javascript folder?

我已将代码添加到我的 investment_time_machine.html.erb 文件中。代码是:

<body id="body">
  <div id="view">
    <ul id="page"></ul>
  </div>
  <script>
    var space = -600;
    var pageSize = 5;
    var angle = 0;
    var data = [];
    var investment_count = <%= @investment_updates.count %>
    var MAX_SIZE = investment_count;
    data.push(new Item(0, 0, 0));
    var current_index = 1;
    var max_index = 0;
    var page = document.getElementById('page');

    function add(n, investment_update){
      if(! data[n]){
        data.push(new Item(data[max_index].translate_y+space, data[max_index].translate_z+space, data[max_index].rotate_z+3));
      }
      var item = document.createElement('li');
      item.id = n;
      item.style.zIndex = (10-n);
      item.onclick = function() {jumpTo(n)};
      item.innerHTML = investment_update
      page.appendChild(item);
      max_index++;
    }

    function Item(translate_y, translate_z, rotate_z){
      this.translate_y = translate_y;
      this.translate_z = translate_z;
      this.rotate_z = rotate_z;
    }

    // displays total investment updates
    <% @investment_updates.each_with_index do |investment_update, index| %>
      data.push(new Item(<%= index + 1 %>*space, <%= index + 1 %>*space, (<%= index + 1 %>-1)*angle));
      add(<%= index + 1 %>, "<%= render 'single_investment_update', investment_update: investment_update %>");
    <% end %>

    // animate total investment updates
    <% @investment_updates.each_with_index do |investment_update, index| %>
      animate(<%= index + 1 %>, 0, 1);
    <% end %>

    function shortCut(event){
      if(event.wheelDelta > 0){
        next();
      }
      else if(event.wheelDelta < 0){
        prev();
      }
    }

    if ("onmousewheel" in document) {
      document.onmousewheel = shortCut;
    } else {
      document.addEventListener('DOMMouseScroll', shortCutFF, false);
    }

    function jumpTo(n){
      for(var i=current_index; i<n; i++){
        next();
      }
    }

    function animate(n, y, opacity) {
      if(n<=MAX_SIZE) {
        var new_y = data[n].translate_y + y;
        var new_z = data[n].translate_z + y;
        var new_rz = data[n].rotate_z + angle*y/space;
        var elementN = document.getElementById(n);
        elementN.onclick = function() {jumpTo(n)};
        elementN.style.webkitTransform = 'translateX('+ (-0.3*new_y) + 'px) translateY('+ new_y + 'px) translateZ(' + new_z + 'px) rotateZ(' + new_rz + 'deg)';
        elementN.style.transform = 'translateX('+ (-0.3*new_y) + 'px) translateY('+ new_y + 'px) translateZ(' + new_z + 'px) rotateZ(' + new_rz + 'deg)';
        elementN.style.opacity = opacity;

        data[n].translate_y = new_y;
        data[n].translate_z = new_z;
        data[n].rotate_z = new_rz;
      }
    }

    function prev() {
      if(current_index >1) {
        document.getElementById(current_index-1).style.opacity = 1;
        current_index --;
        for(var n=1; n<current_index; n++){
          animate(n, space, 0);
        }
        for(var n=current_index; n<current_index+pageSize; n++){
          animate(n, space, 1);
        }
        for(var n=current_index+pageSize; n<=max_index; n++){
          animate(n, space, 0);
        }
      }
    }

    function next() {
      if(current_index < data.length && current_index < MAX_SIZE) {
        document.getElementById(current_index).style.opacity = 0;
        current_index ++;
        if(current_index+pageSize-1>max_index && max_index<MAX_SIZE){
          add(current_index + pageSize -1);
        }
        for(var n=1; n<current_index; n++){
          animate(n, -1*space, 0);
        }
        for(var n=current_index; n<current_index+pageSize; n++){
          animate(n, -1*space, 1);
        }
        for(var n=current_index+pageSize; n<=max_index; n++){   
          animate(n, -1*space, 0);
        }
      }
    }
  </script>
</body>

现在,我必须将此代码放入我的 assets/javascripts 文件夹中。另外,我已经从控制器调用了 @investment_updates,但不知道如何将其添加到资产文件夹中。 另外,我添加了 'jquery-rails' gem 并在我的 application.js 文件中添加了

//= require jquery
//= require rails-ujs
//= require activestorage
//= require turbolinks
//= require bootstrap
//= require_tree .

我尝试了不同的方法但没有成功,这是我第一次在 rails 中使用 javascript。请帮我解决这个问题。

好吧,在我看来,您遇到的问题主要是混合 erb 和 js。我可以用一种简单的方法帮助您解决这个问题。

第 1 步:您可以在 [=38= 的隐藏输入字段中呈现 ruby/rails 变量(即 @investment_updates),而不是混合使用 ruby 代码和 js 代码] 查看文件。因此,将要发生的是服务器将首先呈现您的 html.erb 文件,并且它已经在隐藏的输入字段中包含您的变量 "stored"。注意 JS 代码还没有开始。

第 2 步:现在您需要确保您有一个包含 js 代码的单独文件。假设 investment.js。把它放在和 application.js 文件相同的文件夹中,并在 application.js:

中要求你的 js 文件

//= require jquery //= require rails-ujs //= require activestorage //= require turbolinks //= require bootstrap //= require investment //= require_tree .

第 3 步:确保您的布局文件(可能是 views/layouts 内文件中的 html.erb)标记 <%= javascript_include_tag "application" %>,这是加载 application.js 资产中的文件。这是问题的资产管道部分。

第 4 步:现在让它工作。一旦您确定正在加载此 JS 文件(在文件开头尝试警报或控制台),您可以重构您的 js 代码以操作视图文件中已有的值,而不是处理 ruby/rails 变量。例如:

//in investment.js var index = $("#index").val(); //using the value already written in the view animate(index, 0, 1); ...

另一种方法,如果你真的想将 ruby 代码与 JS 混合,将执行步骤 2 和 3,但使用名为 investment.js.erb 的文件可以解释 ruby 以及 JS。但不是从布局视图调用 <%= javascript_include_tag "application" %>,您可以从您在问题中描述的视图调用 <%= javascript_include_tag "investment" %>(它可能在文件末尾)。 不过,更建议使用方法 1。