По моему опыту, я обнаружил, что лучше всего оставить свои отдельные модули внутри своих закрытий (IIFE). Следующий пример кода демонстрирует ловушкой объединения всех файлов в рамках одного закрытия, а не оборачивать каждый в своем замыкании:
//Your big closure
(function() {
//Included from file 1
var defaultOptions = {
label: 'Testing1'
};
window.MyObject1 = function (options) {
this.options = $.extend({}, defaultOptions, options);
}
//Included from file 2
var defaultOptions = {
label: 'Testing2'
};
window.MyObject2 = function (options) {
this.options = $.extend({}, defaultOptions, options);
}
})();
//Later in the site, you decide to use some objects:
var obj1 = new MyObject1();
var obj2 = new MyObject2();
$('#obj1').text(obj1.options.label);
$('#obj2').text(obj2.options.label);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="obj1"></div>
<div id="obj2"></div>
I обмена данными между модулями за счет использования событий.
Например, у вас есть панель инструментов и диалоговое окно, и вы хотите, чтобы диалог открывался при нажатии кнопки панели инструментов.
(function() {
window.MyToolbar = function() {
this.onOpenDialogButtonClicked = function() {
$(document).trigger(window.events.MyDialog.open); //you can also send it data as the second parameter if you need to.
};
};
})();
(function (events) {
//Define your custom events for this dialog.
$.extend(events, {
MyDialog: {
open: 'window.events.myDialog.open' //Need a unique string here. I go back later and CRC32 these to help with minification.
}
});
window.MyDialog = function() {
$(document).on(window.events.MyDialog.open, function() {
//open the dialog here!
$('#dialog').text('opened!');
});
};
})(window.events = window.events || {});
var toolbar = new MyToolbar();
var dialog = new MyDialog();
$(document).on('click', '#button', toolbar.onOpenDialogButtonClicked);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button id="button">Open Dialog</button>
<div id="dialog"></div>
Преимущество здесь в том, что нет нагрузки зависимости заказа требуется. В этом примере модуль панели инструментов требует, чтобы диалоговый модуль загружался для window.events.MyDialog.open
, чтобы разрешить его, но это потребуется только при нажатии кнопки.
Если это проблема, вы можете перенести объявления событий в один файл с именем events.js
или что-то в этом роде.
За исключением имени события, кнопка панели инструментов может быть нажата, и для ее открытия не требуется ссылка на диалог. Диалог прослушивает открытое событие. Если он получит один, он откроется сам. Если ни один диалог не прослушивается, кнопка просто ничего не делает.
В этом примере также показано, как модули могут связываться, присоединяя элементы к глобальному пространству, предназначенным для глобального пространства. Лично я создаю переменную «namespace», которая сидит в глобальном пространстве и присоединяет к ней все мои вещи.
Например:
(function (myNamespace) {
//This is assuming myNamespace.events exists already - make sure it does before calling this.
$.extend(myNamespace.events, {
MyDialog: { open: 'myNamespace.events.MyDialog.open' }
});
})(window.myNamespace = window.myNamespace || {});
Это просто инкапсулирует материал, который я написал, и держит его от столкновения с вещами других библиотек может разместить в глобальном пространстве.
Таким образом, в то время как вы можете сэкономить несколько байт в процессе минификации конкатенации всех файлов в одном закрытие, вы можете попасть в какие-нибудь ненужные проблемы. С включением minification и gzip несколько байтов, которые вы сохранили бы от конкатенации всего под одним закрытием, несущественны.
Я показал, как замыкания могут взаимодействовать друг с другом и скрыть элементы, которые являются частями модуля.
Я не использовал Backbone.js, поэтому извините за то, что в примерах не было никаких материалов Backbone.js. Я уверен, что идеи переводится.
Вы не хотите, чтобы каждый файл был завернут в свое закрытие? – crush
@crush нет, поскольку мне нужно, чтобы они взаимодействовали друг с другом, но я все еще довольно новичок в использовании IIFE, поэтому, если это не так, не стесняйтесь исправлять меня :) – Prefix
Вы все еще можете взаимодействовать между ними, как долго поскольку материал, который вам нужен, находится на вашем объекте 'app', как определено выше. Я бы, вероятно, явно установил 'app' как часть' window', но эта глобальная переменная была бы доступна в каждом отдельном закрытии. Это также позволяет вам иметь закрытые конкретные переменные - например, переменную 'defaultOptions'. Если вы объединяете кучу модулей вместе, которые имеют 'defaultOptions', и помещают их все в одно и то же закрытие, последняя переменная' defaultOptions' будет значением, используемым всеми модулями, что, вероятно, является непреднамеренным. – crush