У меня есть проблема, о которой нелегко описать. Я пишу веб-приложение, которое сильно использует вызовы jQuery и AJAX. Теперь у меня нет большого опыта в архивировании Javascript, но я понимаю, что у моей программы нет хорошей структуры. Я думаю, что у меня слишком много идентификаторов, относящихся к одной и той же (по крайней мере, более или менее) вещи.
Посмотрим на произвольный примерный виджет пользовательского интерфейса, который составляет небольшую часть приложения: виджет может быть частью окна, и это окно может быть частью диспетчера окон:
- Обработчики событий используют элементы 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\ up?');
В этот момент у меня есть обертка вокруг HTMLDivElement (размещенного объекта). Имея экземпляр регистратора (собственный объект) под рукой, я могу легко работать с ним через функцию logger.getRootEl().
Где я застрял, когда у меня есть только элемент DOM, и вам нужно что-то сделать с публичным API, возвращаемым функцией makeLogger (например, в обработчиках событий). И здесь начинается беспорядок. Мне нужно сохранить все собственные объекты в репозитории или что-то еще, чтобы я мог снова получить. Было бы гораздо приятнее иметь соединение (например, свойство объекта) с размещенным объектом с моим исходным объектом.
Я знаю, что это можно сделать, но у него есть некоторые недостатки:
- Эти типы (круговые) ссылки потенциально распространяются на IE7
- Когда передать размещенный объект и когда передать собственный объект (в функциях)?
В настоящее время я делаю обратную ссылку с помощью метода jQuery data(). Но в целом мне не нравится, как мне приходится отслеживать связь между размещенным объектом и его родным коллегой.
Как вы справляетесь с этим сценарием?
<Б > EDIT3:
После некоторого понимания, которое я получил от примера Анурага.
@Anurag: Если я правильно понял ваш пример, критическая точка состоит в том, чтобы установить правильное (что правильно зависит от ваших потребностей, хотя) контекст выполнения для события обработчики. И это в вашем случае экземпляр объекта презентации, который выполняется с помощью функции Mootool bind(). Таким образом, вы гарантируете, что вы ВСЕГДА имеете дело с объектом-оболочкой (я назвал его родным объектом) вместо объекта DOM, правильно?
Примечание для читателя: Вы не должны использовать Mootools для достижения этого. В jQuery вы должны настроить обработчики событий с помощью функции $.proxy(), или если вы используете простой старый Javascript, вы должны использовать свойство apply, которое предоставляет каждая функция.