Как вы организовываете большие кодовые базы JS/jQuery на весь ваш сайт? Есть много хороших ресурсов для того, как организовать фрагменты вашего кода, но ничего не стоит о том, как собрать все это вместе и подгонять каждую деталь на месте: организация с широким кодом, несколько страниц с использованием того же кода, оставаясь СУХОЙ с свободной связью, и др.
Ниже я расскажу, как я с этим справляюсь. Мне никогда не нравилось организовывать мой код, как это, потому что я думаю, что он неряшлив и может привести к проблемам с ремонтопригодностью/масштабированием, но я не знаю ничего лучше.
Я понимаю, что у каждого из нас свой набор требований и нет решений "под ключ", но я люблю слышать некоторые мнения о том, что я делаю неправильно, ПОЧЕМУ Я делаю это неправильно, и предложения о том, как писать более удобный код.
То, что я думаю, я действительно пытаюсь понять:
-
Как вы справляетесь с логикой, что вы необходимо использовать в нескольких местах, на несколько страниц?
-
Как вы организовываете страницы код? Является ли размещение имен каждой страницы в глобальный объект - хорошая идея? 1.
-
Что вы делаете с самого начала не заставляйте вас постоянно переиздание вашей организации как ваше приложение растет и больше? Возможно, я на 4-м итерация, пишущая эту вещь .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% кода в этих файлах требует() "виджета и инициализации".
Я использую 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(){
}
}
};