У меня есть проблема, которую нелегко описать. Я пишу веб-приложение, которое активно использует вызовы jQuery и AJAX. Сейчас у меня нет большого опыта работы с Javascript archicture, но я понимаю, что моя программа не имеет хорошей структуры. Я думаю, что у меня слишком много идентификаторов, ссылающихся на одну и ту же (по крайней мере, более или менее) вещь.
Давайте посмотрим на произвольный примерный виджет пользовательского интерфейса, который составляет крошечную часть приложения: виджет может быть частью окна, а окно может быть частью оконного менеджера:
- Обработчики событий используют элементы DOM в качестве параметров. Элемент DOM представляет виджет в браузере.
- Много раз я использую объекты jQuery (в основном обертки вокруг элементов DOM), чтобы что-то делать с виджетом. Иногда они используются временно, иногда они сохраняются в переменной для более поздних целей.
- Вызовы функций AJAX используют строковые идентификаторы для этих виджетов. Они обрабатываются на стороне сервера.
- Кроме того, у меня есть класс виджетов, экземпляры которого представляют виджет. Он создается через новый оператор.
Теперь у меня есть как-то четыре разных идентификатора объекта для одной и той же вещи, которые нужно синхронизировать до тех пор, пока страница не будет загружена заново. Это, кажется, не очень хорошая вещь.
Любой совет?
EDIT:
@ Will Morgan : это дизайнер форм, который позволяет создавать веб-формы в браузере. Бэкэнд - Zope, сервер веб-приложений на Python. Трудно получить более ясное объяснение, так как это общая проблема, которую я наблюдаю все время, когда делаю Javasscript-разработку с трио jQuery, DOM-деревом и моими собственными экземплярами класса-прототипа.
EDIT2:
Я думаю, что было бы полезно сделать пример, хотя и искусственный. Ниже вы видите виджет журнала, который можно использовать для добавления элемента блока на веб-страницу, на которой отображаются зарегистрированные элементы.
makeLogger = function(){
var rootEl = document.createElement('div');
rootEl.innerHTML = 'Logged items:';
rootEl.setAttribute('class', 'logger');
var append = function(msg){
// append msg as a child of root element.
var msgEl = document.createElement('div');
msgEl.innerHTML = msg;
rootEl.appendChild(msgEl);
};
return {
getRootEl: function() {return rootEl;},
log : function(msg) {append(msg);}
};
};
// Usage
var logger = makeLogger();
var foo = document.getElementById('foo');
foo.appendChild(logger.getRootEl());
logger.log('What\'s up?');
На данный момент у меня есть обертка вокруг HTMLDivElement (размещенный объект). Имея экземпляр logger (собственный объект) под рукой, я могу легко работать с ним с помощью функции logger.getRootEl () .
Я застреваю, когда у меня есть только элемент DOM, и мне нужно что-то делать с открытым API, возвращаемым функцией makeLogger (например, в обработчиках событий). И вот тут начинается беспорядок. Мне нужно держать все нативные объекты в хранилище или что-то еще, чтобы я мог получить снова. Было бы намного приятнее иметь соединение (например, свойство объекта) с размещенного объекта обратно к моему нативному объекту.
Я знаю, что это можно сделать, но у него есть некоторые недостатки:
- Этот вид (циклических) ссылок может привести к утечке памяти до IE7
- Когда передавать размещенный объект и когда передавать собственный объект (в функциях)?
Сейчас я делаю обратную ссылку с помощью метода jQuery data (). Но в целом мне не нравится, как я должен отслеживать отношения между размещенным объектом и его нативным аналогом.
Как вы справляетесь с этим сценарием?
EDIT3:
После некоторого понимания я получил от примера Anurag ..
@ Anurag: Если я правильно понял ваш пример, критический момент - установить правильное (хотя правильное зависит от ваших потребностей) контекст выполнения для обработчиков событий. И это в вашем случае экземпляр объекта презентации, который выполняется с помощью функции bind () Mootool. Таким образом, вы гарантируете, что вы ВСЕГДА имеете дело с объектом-оболочкой (я назвал его нативным объектом) вместо объекта DOM, верно?
Примечание для читателя: Вы не обязаны использовать Mootools для достижения этой цели. В jQuery вы бы настраивали свои обработчики событий с помощью функции $. Proxy () , или, если вы используете простой старый Javascript, вы бы использовали свойство apply , которое предоставляет каждая функция ,