#javascript #jquery #design-patterns #frameworks
#javascript #jquery #шаблоны проектирования #фреймворки
Вопрос:
На всякий случай, если это имеет значение, я использую ASP.NET 3.5 с VB.NET . У меня есть вложенные мастер-страницы и панели обновлений с частичными обратными отправками. Я включаю Modernizr 1.7 с прокладкой YepNopeJs / IE в свой раздел head. Прямо перед закрывающим тегом body я включаю свой jQuery 1.6, jQuery UI 1.8.12 и это script.js Я пытаюсь собрать.
Я подумываю использовать что-то вроде:
SITE = {
PAGES : { ... },
VARS : { ... },
HELPERS : { ... },
PLUGINS : { ... },
init : function() { ... }
};
SITE.init();
Обновить
Хорошо, следуя совету Леви, я придумал это решение:
var SFAIC = {}; // Global namespace
SFAIC.common = { ... }; // Shared properties
SFAIC.common.fn = { ... }; // Shared functions
SFAIC.plugin = {
qtip: $.fn.qtip,
validate: $.fn.validate,
validator: $.fn.validator
};
SFAIC.init = function() { ... }; // Global initializer
$(document).ready(function() { SFAIC.init(); });
Тогда каждая страница имела бы свой собственный объектный литерал, подобный:
SFAIC.Main = {}; // Main.aspx
SFAIC.Main.someSection = { ... }; // Some Section's properties
SFAIC.Main.someSection.fn = { ... }; // Some Section's functions
SFAIC.Main.anotherSection = { ... }; // Another Section's properties
SFAIC.Main.anotherSection.fn = { ... }; // Another Section's functions
SFAIC.Main.init = function() { ... }; // Main.aspx's intializer
$(document).ready(function() { SFAIC.Main.init(); });
Комментарии:
1. Насколько велик рассматриваемый веб-сайт? Это может иметь отношение к ответу.
2. Это своего рода вопрос с подвохом. Веб-сайт небольшой с точки зрения страниц. С точки зрения кода, он огромен. С точки зрения клиентской части, это где-то от пары сотен до тысячи строк кода на страницу. Однако я думаю, что этот объектный литерал — это тот путь, которым я ХОЧУ пойти, и, вероятно, он наиболее практичен. Я просто не знаю точно лучшего способа поместить весь код в объектный литерал и выполнить на основе страницы.
3. Обратите внимание, что в jQuery это
.fn
фактически означает.prototype
, что это способ определения методов в объекте jQuery, а не поле для хранения функций. Это может ввести в заблуждение, если вы сравниваете его сjQuery.fn
4. Да, это меня смутило. Мне нужен был ящик для хранения моих функций. Есть ли что-то лучше или способ смешать prototype с объектными литералами?
Ответ №1:
Я рекомендую вам создать новый объект для section и новую функцию для каждой страницы / элемента.Однако, чем больше скриптов вы добавляете таким образом, тем сложнее становится управлять целым в редакторе. В Netbeans есть функция, которая позволяет вам переходить к частям объекта и помогает управлять этим.
Пример:
var lib = {}; // your library
//maybe you like the plural name plugins better. That's fine.
lib.plugin = {
//define plugins here
};
//maybe you like the plural name helpers better. That's fine too.
lib.helper = {
//define your helpers here
cycle: function() {
//code for the cycle plug-in
}
};
lib.account = {
//you could stick code that is general to all account pages here
};
lib.account.overview = function() {
//you could stick code that is specific to the account overview page here
//maybe you'd use the cycle plug-in to show their latest posts.
lib.plugin.cycle();
};
lib.account = {
//you could stick code that is general to all account pages here
};
lib.account.overview = function() {
//you could stick code that is specific to the account overview page here
//maybe you'd use the cycle plug-in to show their latest posts.
lib.plugin.cycle();
};
Затем на странице обзора учетной записи вы бы позвонили lib.account.overview()
.
Комментарии:
1. Вопрос. Допустим, я использую плагин validation jQuery и плагин qtip2 jQuery. Оба подключаются к
$.fn
with$.extend
. Следовательно, я мог бы получить к ним доступ$.fn.validate
,$.fn.validator
или$.fn.qtip
. Было бы лучшей практикой создать,lib.plugin = { qtip: $.fn.qtip, validate: $.fn.validate, validator: $.fn.validator };
где я мог бы использоватьlib.plugin.validator
,lib.plugin.qtip
и т.д. Или мне даже не следует беспокоиться об объекте lib.plugin и использовать$.fn
маршрут?2. Все, что можно было бы сделать с
lib.*
записями, это включить их для этой страницы. Вы могли бы продолжить использовать их как обычно. Кроме того, вы хотели бы использовать неуменьшенную версию скриптов в подключаемом модуле, поскольку их можно было бы еще больше сократить, включив в гигантский скрипт. Я настоятельно рекомендую, чтобы у вас был хороший редактор при использовании этого метода. Потому что это может занять довольно много времени.3. Я использую VS2008, и вскоре мы переходим на VS2010. Я бы счел это лучшим редактором на рынке. Насколько мой plugins.js для разработки я использую неминифицированные версии всех моих плагинов. У меня есть plugins.min.js у которых есть упакованные или уменьшенные версии, которые я использую в режимах rc и production. Я предполагаю, что мой вопрос скорее предпочтительный, но было любопытно, переносят ли люди $.fn.xxx в lib.plugin.xxx для удобства чтения или они предпочитают просто использовать $.fn.xxx. Я своего рода помешанный на организационной аккуратности, когда дело доходит до моего кода. Я часто переоцениваю эти вещи, я думаю.
4. Все, на чем можно жить
$.fn.method
… etc не следует вызывать напрямую. вы должны вызвать$(selector).method
. Вам следует избегать прямого доступа к ним или расширения их.5. Ну, возьмем, к примеру, плагин qTip . Его значения по умолчанию находятся в
$.fn.qtip.defaults
, поэтому Крейг рекомендует их изменить$.fn.qtip.defaults = $.extend(true, {}, $.fn.qtip.defaults, { ... });
. Или, если у вас есть необходимость изменить свойство, которое не отображается по умолчанию, например zindex, вы должны сделать$.fn.qtip.zindex = getMaxZIndex();
. Я не хочу выполнять$("#tooltip").qtip.zindex = getMaxZIndex();
or$("#tooltip").qtip({ ... my defaults here ... });
для каждого отдельного вызова. Вот почему вы получаете доступ напрямую и устанавливаете значения по умолчанию один раз.
Ответ №2:
Для производства:
Используйте пакет типа closure, uglify или тот, который я упоминаю в конце, чтобы упаковать весь ваш код в один файл и отправить его.
Для разработки:
Я бы рекомендовал для структуры использовать асинхронный загрузчик javascript, такой как
Это означает, что у вас много модулей, и вы конкретно указываете зависимости.
Например, у вас был бы один main.js
// main.js
require([
"jquery.js",
"jquery.ui.js",
...
], function() {
// if the correct location is "mysite.com/foo/" then url will be "foo"
var url = window.location.pathname.match(//(w )//)[1] || "mainpage";
require(url ".js", function(pageObj) {
// ...
});
});
// foo.js
define({
pageStuff: ...
});
Я рекомендую вам ознакомиться с документами RequireJS, чтобы понять их систему структурирования. Это одно из лучших, что я нашел.
Когда дело доходит до оптимизации всего javascript в один файл, вы просто используете их конструктор. Это должно быть частью вашей системы развертывания проекта.
Комментарии:
1. Хотя это действительно не делает того, что я хочу. У меня уже есть моя система, созданная с использованием js-файла для каждой страницы, где у меня есть возможность через ContentPlaceHolders включать js-файл этой страницы без необходимости загрузки. Если по какой-либо причине я хотел пойти по пути загрузчика, я использую Modernizr, который использует YepNopJs, так что я мог бы просто использовать это, если бы захотел. Но, поскольку я больше не хочу поддерживать все разные js-файлы, и я хочу, чтобы они все были в одном js-файле, чтобы у меня был intellisense в Visual Studio, вот почему я спрашиваю то, что я спрашиваю.
2. @Scott Один гигантский файл со всеми данными был бы для меня кошмаром. Если бы все мои методы / функции были настроены подобным образом в одном большом глобальном объекте, это привело бы к слишком большой жесткой связи.
3. @Raynos — Я просто следую совету Пола Айриша и ему подобных, в которых говорится, что нам нужно объединить js в один plugins.js файл и один script.js файл для кроссбраузерной оптимизации.
4. @Scott Я согласен с этим. Для этого вам просто нужно использовать инструмент автоматического построения, подобный тому, который я связал. Вы не записываете все это в один файл.
5. @Raynos: Я не согласен с этим методом по нескольким пунктам, но я попросил масштаб для веб-сайта, как будто он действительно большой, тогда метод, который я опубликовал, становится немного запутанным. У каждого есть свои сильные стороны и преимущества.