如何将 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。
我已将代码添加到我的 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:
//= 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。