【发布时间】:2010-09-08 14:05:26
【问题描述】:
您如何在整个网站上组织大型 JS/jQuery 代码库?有很多关于如何组织代码片段的好资源,但没有真正关于如何将它们组合在一起并将每个片段放置到位:横向代码组织,使用相同代码的多个页面,保持 DRY 松散耦合,等等
以下是我的处理方法。我从来没有习惯像这样组织我的代码,因为我认为它很草率并且可能导致可维护性/可扩展性问题,但我真的不知道更好。
我意识到我每个人都有自己的一套要求,并且没有统包解决方案,但我很想听听一些关于我做错了什么、为什么我做错的意见,以及关于如何做的建议编写更易于维护的代码。
我认为我真正想要达到的目的:
你如何处理你的逻辑 需要在多个地方使用,在 多页?
如何组织特定页面 代码?将每个页面命名为 全局对象是个好主意吗?1.
你从一开始做什么 确保你不会经常 重写你的组织 应用程序变大时的模式 和更大?我可能在我的 4th 迭代写这个东西。2.
每个页面都接收到主 application.js 文件。每个附加页面都有自己的 application.pagename.js 文件。我使用服务器端逻辑来包含文件(首先检查以查看 如果该页面甚至存在一个 - 有些页面不需要 JS),然后按顺序初始化它们。
所以我的主页看起来像:
<script src="js/application.js"></script>
<script src="js/application.index.js"></script>
<script>
MyApp.init();
MyApp.index.init();
</script>
我的 URL 约定是 /page/subpage/id/。我有大约 10 页和一大堆子页面,每个子页面都需要自己的逻辑。请参阅本文中的最后一个示例。
我的大部分代码已经模块化为 jQuery UI 小部件或 jQuery 插件,所以我想说这些文件中 75% 的代码是 require()'ing 一个小部件并对其进行初始化。
我根据需要使用 requireJS 来拉入小部件。
// application.js
var MyApp = {
init: function(){
var self = this;
// these widgets are available on every single page
// notice the call to jquery.deparam.js - i'll use this later to init subpage logic.
require(['js/widget1.js', 'js/widget2.js', 'js/widget3.js', 'js/jquery.deparam.js'], function(){
// deparam the query string. I'll use this later.
self.querystring = $.deparam.querystring();
// init widgets once the document is ready
$(function(){
$("#widget1").widget1();
$("#widget2").widget2();
// make these bindings available immediately as well.
self.rebindable();
});
});
},
// I use jQuery UI Dialog extensively as a window manager, and each dialog is loaded
// via an AJAX request. I'll call this method after each AJAX request to
// rebind some key widgets.
rebindable: function(){
$("#widget3").widget3();
}
};
// application.index.js
// home page specific stuff. this file is only included on the home page.
MyApp.index = {
// my convention is that init is automatically called after the script
// is included in a page, outside of a doc.ready statement.
init: function(){
var self = this;
require(['js/widget4.js'], function(){
$(function(){
self.widget4( $("#foo") );
});
});
},
// passing elements to each method allows me to call this init code
// outside of the index page. I can require() this file, and only init
// widget4, and even use a different element.
widget4: function( element ){
var config = {
something: "custom to the home page"
};
element.widget4( config );
}
};
// application.foo.js
// page "foo" stuff
MyApp.foo = {
init: function(){
var self = this;
// this page happens to use the same widget3 and configuration present
// in MyApp.index. this is where things can get sloppy and unmaintainable
// really quickly.
require(['js/application.index.js'], function(){
$(function(){
MyApp.index.widget3( $("#bar") );
});
});
// page "foo" has three subpages (or actions) and require
// their own logic. url convention: /foo/subpage1/
// init whichever page we're on...
switch( self.querystring.subpage ){
case "subpage1":
self.subpage1.init();
break;
case "subpage2":
self.subpage2.init();
break;
case "subpage3":
self.subpage3.init();
break;
}
},
subpage1: function(){
init: function(){
var self = this;
// once the DOM is ready init dialog.
$(function(){
self.dialog( $("#openDialog") );
});
},
dialog: function( element ){
element.bind("click", function(){
$('<div></div>').dialog({
open: function(){
// see what i'm doing here?
MyApp.rebindable();
// maybe more bindings specific to this
// dialog here
}
});
});
}
},
subpage2: function(){
init: function(){
}
},
subpage3: function(){
init: function(){
}
}
};
【问题讨论】:
-
这周我自己也在考虑这个问题。我最近加入了一个项目团队,担任主要的 javascript 编码员。该项目已经进行了一年多,所以他们到处都有 javascript。他们积累了大量的 javascript 库,并在使用命名空间方面做出了一些努力,但是很多页面都有自定义的 javascript,这些 javascript 不仅是在页面和用户控件中编写的,还有一些是基于页面或用户控件数据生成的。我的艰巨任务是理解这一切并尽可能地标准化。
-
(续)您的方法是一个好的开始,但我可以看到它无法维护的地方。也许您可以设计一种配置页面和控件的方法,这样您就不必使用很多 switch 语句。您还可以查看 Claypool (http://www.claypooljs.com) 看看是否有帮助。
-
@Silkster 链接已损坏:http//www.claypooljs.com
-
貌似移到了 jQuery 网站:docs.jquery.com/Plugins/Claypool
标签: javascript jquery