在 Rails 中分隔页面特定 JavaScript 的面向对象方法
Object-oriented way to separate page-specific JavaScript in Rails
假设我有一个基本的 Rails 应用程序,其中包含三种资源:authors
、blogs
和 books
。我使用 scaffold
命令创建资源,因此每个资源都有自己的 JavaScript 文件:authors.js
、blogs.js
和 books.js
.
我看到了几个不同的实现,关于如何为我们的 JavaScript 保持全局命名空间的清洁,以及如何使我们的页面特定 JavaScript 彼此分开,这样它们就不会冲突。
这是我设计的实现。它似乎做我想做的事,但如果由于某种原因这被认为是不好的 implementation/bad 做法,我想得到反馈。如果人们有更好的方法,我也欢迎其他实现。
对于 app/views/layouts
中的所有布局,请为 body
标签指定:
<body class="<%= controller_name %>">
对于 JavaScript 代码:正如我们所知,Rails 中的所有 JavaScript 最终会被拉到一个大的 JavaScript 文件中。为了这里的可读性目的,我从每个单独的 JavaScript 文件中提取了所有 JavaScript 并将它们放在一起(在应用程序中,我将在每个相应的 js 文件中将 JavaScript 代码分开):
var authorsjs = {
init: function(){
alert("hello from authorjs");
// all author bindings specified here
$("#oneEl").on('click', function(){
alert("oneEl was clicked");
});
},
someAuthorFunc: function(){
alert("someAuthorFunc run");
}
};
$(document).on('page:change', function(){
if($('body').hasClass("authors") == true ){
authorsjs.init();
}
});
var booksjs = {
init: function(){
alert("init booksjs run");
// all books bindings specified here
$("#twoEl").on('click', function(){
alert("twoEl was clicked");
});
},
someBookFunc: function(){
alert("someBookFunc run");
}
};
$(document).on('page:change', function(){
if($('body').hasClass("authors") == true ){
authorsjs.init();
}
});
因此,正如预期的那样,这些点击事件不适用于与 blogs
关联的视图,绑定到 #oneEl
的事件仅适用于与作者关联的视图,并且绑定到 [=25] 的事件=] 仅适用于与书籍相关的视图。
根据反馈回答
以下作品。我正在使用 jquery-turbolinks gem。 controller的每一个js都封装在一个对象中。对于每个页面请求,检查 body
class 并且相应对象的 init
方法是 运行。我还继续创建了一个 someGlobals
对象,它提供了所有控制器的通用 js 代码。
此代码按预期工作,但非常混乱。我希望有一些方法可以清理前端代码。如果您有任何建议,请告诉我:
$(document).ready(function(){
var authorsjs = {
init: function(){
alert("hello from authorjs");
// all author bindings specified here
$("#oneEl").on('click', function(){
alert("oneEl was clicked");
});
},
someAuthorFunc: function(){
alert("someAuthorFunc run");
}
};
if($('body').hasClass("authors") == true ){
authorsjs.init();
}
});
$(document).ready(function(){
var booksjs = {
init: function(){
alert("init booksjs run");
// all books bindings specified here
$("#twoEl").on('click', function(){
alert("twoEl was clicked");
booksjs.someBookFunc();
});
},
someBookFunc: function(){
alert("someBookFunc run");
}
};
if($('body').hasClass("booksjs") == true ){
booksjs.init();
}
});
$(document).ready(function(){
var blogsjs = {
init: function(){
blogsjs.formValidations();
},
formValidations: function(){
$('#blog_title').on("click", function(){
console.log($(this).val());
$('p').css("color", "green");
$(this).css("color", "blue");
alert("hello");
});
$('#blog_title').on("keypress", function(){
var value = $(this).val();
$("#preview").text(value);
});
}
};
if($('body').hasClass("blogs") == true){
blogsjs.init();
}
});
$(document).ready(function(){
var someGlobals = {
init: function(){
$('p').on('click', function(){
alert("Global: P was clicked somehwere!");
})
}
};
someGlobals.init();
});
假设我有一个基本的 Rails 应用程序,其中包含三种资源:authors
、blogs
和 books
。我使用 scaffold
命令创建资源,因此每个资源都有自己的 JavaScript 文件:authors.js
、blogs.js
和 books.js
.
我看到了几个不同的实现,关于如何为我们的 JavaScript 保持全局命名空间的清洁,以及如何使我们的页面特定 JavaScript 彼此分开,这样它们就不会冲突。
这是我设计的实现。它似乎做我想做的事,但如果由于某种原因这被认为是不好的 implementation/bad 做法,我想得到反馈。如果人们有更好的方法,我也欢迎其他实现。
对于 app/views/layouts
中的所有布局,请为 body
标签指定:
<body class="<%= controller_name %>">
对于 JavaScript 代码:正如我们所知,Rails 中的所有 JavaScript 最终会被拉到一个大的 JavaScript 文件中。为了这里的可读性目的,我从每个单独的 JavaScript 文件中提取了所有 JavaScript 并将它们放在一起(在应用程序中,我将在每个相应的 js 文件中将 JavaScript 代码分开):
var authorsjs = {
init: function(){
alert("hello from authorjs");
// all author bindings specified here
$("#oneEl").on('click', function(){
alert("oneEl was clicked");
});
},
someAuthorFunc: function(){
alert("someAuthorFunc run");
}
};
$(document).on('page:change', function(){
if($('body').hasClass("authors") == true ){
authorsjs.init();
}
});
var booksjs = {
init: function(){
alert("init booksjs run");
// all books bindings specified here
$("#twoEl").on('click', function(){
alert("twoEl was clicked");
});
},
someBookFunc: function(){
alert("someBookFunc run");
}
};
$(document).on('page:change', function(){
if($('body').hasClass("authors") == true ){
authorsjs.init();
}
});
因此,正如预期的那样,这些点击事件不适用于与 blogs
关联的视图,绑定到 #oneEl
的事件仅适用于与作者关联的视图,并且绑定到 [=25] 的事件=] 仅适用于与书籍相关的视图。
根据反馈回答
以下作品。我正在使用 jquery-turbolinks gem。 controller的每一个js都封装在一个对象中。对于每个页面请求,检查 body
class 并且相应对象的 init
方法是 运行。我还继续创建了一个 someGlobals
对象,它提供了所有控制器的通用 js 代码。
此代码按预期工作,但非常混乱。我希望有一些方法可以清理前端代码。如果您有任何建议,请告诉我:
$(document).ready(function(){
var authorsjs = {
init: function(){
alert("hello from authorjs");
// all author bindings specified here
$("#oneEl").on('click', function(){
alert("oneEl was clicked");
});
},
someAuthorFunc: function(){
alert("someAuthorFunc run");
}
};
if($('body').hasClass("authors") == true ){
authorsjs.init();
}
});
$(document).ready(function(){
var booksjs = {
init: function(){
alert("init booksjs run");
// all books bindings specified here
$("#twoEl").on('click', function(){
alert("twoEl was clicked");
booksjs.someBookFunc();
});
},
someBookFunc: function(){
alert("someBookFunc run");
}
};
if($('body').hasClass("booksjs") == true ){
booksjs.init();
}
});
$(document).ready(function(){
var blogsjs = {
init: function(){
blogsjs.formValidations();
},
formValidations: function(){
$('#blog_title').on("click", function(){
console.log($(this).val());
$('p').css("color", "green");
$(this).css("color", "blue");
alert("hello");
});
$('#blog_title').on("keypress", function(){
var value = $(this).val();
$("#preview").text(value);
});
}
};
if($('body').hasClass("blogs") == true){
blogsjs.init();
}
});
$(document).ready(function(){
var someGlobals = {
init: function(){
$('p').on('click', function(){
alert("Global: P was clicked somehwere!");
})
}
};
someGlobals.init();
});