Управление последовательностью загрузки элементов управления AJAX на странице - PullRequest
3 голосов
/ 28 июня 2011

Я думаю, что я испытываю условия гонки с веб-приложением AJAX.Я использую JQuery 1.4.4 для обработки запросов AJAX.

У меня есть элемент управления / класс меню, который пользователь нажимает, чтобы отобразить элементы управления для манипулирования данными.Щелкнув по меню, можно отобразить несколько элементов управления, которые инициализируются независимо друг от друга, загружаются с разными скоростями и становятся доступными в непредсказуемом порядке (думаю, A в AJAX ...).

Элементы управления взаимодействуют друг с другом,например, выбор элемента в одном элементе управления добавляет его к другому.Взаимодействие происходит путем запуска события в элементе управления источника с использованием JQuery и привязки к этому событию в элементе управления назначения.Кажется, проблема заключается в том, что когда вы начинаете взаимодействовать с элементом управления до завершения инициализации всех элементов управления, это может вызвать проблемы.Например, добавление элемента, по-видимому, работало в элементе управления источником, пока элемент управления назначения все еще загружается, но когда он загружен, он не показывает добавленный элемент.Я думаю, что это потому, что запрос на добавление элемента запускается и завершается, в то время как загрузка все еще происходит, что затем перезаписывает любые изменения.

Целью разработки элементов управления было сохранить их как независимые друг от друга, так каквозможно и для них не вызывать напрямую друг к другу методы и свойства, если это возможно.Те же элементы управления используются в различных контекстах и ​​не знают, какие другие элементы управления отображаются одновременно.Существует центральный класс, который управляет отображением и скрытием элементов управления - меню.

Может ли кто-нибудь предложить подход, который позволил бы сохранить элементы управления / классы слабо связанными, но иметь возможность управлять зависимостями между ними и знатькогда можно разрешить взаимодействие?

Ниже приведены несколько идей.Любые мысли по поводу этих или дальнейших предложений приветствуются.

  1. Класс меню может поддерживать некоторый тип флага, который указывает, когда все элементы управления инициализируются - это будет основано, например, на увеличении числа, которое увеличивается при успешной загрузке каждого элемента управления.Это единственный класс, который знает об элементах управления, которые используются в данный момент, но это делается общим способом, когда элементы управления передают себя для отображения.

  2. Загруженные события запускаютсякаждый элемент управления и другие элементы управления, отображаемые в этом контексте, привязываются к загруженному событию друг друга.Элементы управления должны знать больше о контексте, в котором они используются, чтобы они знали, когда они были последними загруженными элементами управления, и, таким образом, страница была готова к взаимодействию.

  3. Реализация очереди запросов, которые выполняются после загрузки страницы.Это выглядит немного слишком синхронно.

  4. Обновление до JQuery 1.6.2 находится на рассмотрении, но не запланировано.Я не уверен, что задержка будет правильным вариантом в любом случае из-за общего / анонимного характера элементов управления.

Спасибо за вашу помощь

Ответы [ 2 ]

3 голосов
/ 28 июня 2011

В 2007/08 году я работал над проектом, работающим на Ajax, что означает, что несколько страниц довольно много взаимодействовали и обрабатывали страницы перед тем, как были перезагружены другой страницей. Основная идея состояла в том, чтобы приложение (или страницы) имело центральный контроллер, который отделял отдельные элементы управления друг от друга, в то же время обеспечивая функциональность для управления взаимодействием. Типичным сценарием страницы было отображение древовидной структуры (с различными элементами разных типов), с которой взаимодействовал пользователь. На основе этого взаимодействия были отображены другие элементы управления (например, основной список или список сведений, форма создания / изменения и т. Д.), С которыми взаимодействовали.

В любом случае. Как все это работало?

Контроль взаимодействия - предопределенный конечный набор событий

Я написал своего рода контроллер страниц javascript, чтобы каждая страница взаимодействовала с ним. Я также представил набор предопределенных событий. К большинству этих событий были прикреплены метаданные об элементе / группе, какими бы они ни были. В приложении было около 50 различных предопределенных событий. Каждое событие было определено этими:

  • особый тип: т.е. ActivityGroupEvent
  • действие события: выбрать, выбрать, создать, создать, удалить, удалить, изменить, изменить, удалить, удалить, удалить, удалить, отбросить незначительное
  • необязательные метаданные: метаданные были в основном связаны с элементом, о котором это событие имело

Отделение управления - центральная обработка событий

Вся обработка событий (которая не была связана с внутренней работой элемента управления, например событиями щелчка и т. Д.) Была обработана через контроллер страниц.

Каждый элемент управления (когда он создавался сам) имел функцию инициализации, которая автоматически подписывалась на определенные типы событий (т. Е. Элемент управления представлением сведений об элементе подписывался на событие выбора элемента). Подписка на события позволила элементам управления быть полностью независимыми друг от друга. Поэтому, когда произошло событие select item , поднятый подписанный элемент управления получил его независимо от того, откуда он возник. Было ли это из основного вида или левого дерева, в котором также могли отображаться отдельные элементы.

Динамические элементы управления страницей - создание элементов управления по требованию

Обработка страницы также инициализировала событие по требованию управления загрузкой. Поэтому при возникновении определенного события контроллер страницы Ajax загружал определенные элементы управления перед отправкой события. Сами контроли тогда позаботились о своей жизни. Но все они включали (унаследовали один и тот же прототип javascript) функциональные возможности, чтобы информировать контроллер страниц об их удалении, поэтому контроллер страниц перезагружал их при необходимости.

Почему пары событий, например, удаляются / удаляются?

Идея состоит в том, что когда пользователь щелкает значок удаления элемента (например), на уровне страницы поднимается delete event. Контроллер страницы, отправивший это событие подписанным элементам управления, обработавшим его.

Пример: текущая страница отображает левое дерево, основной вид и подробный вид.

  1. Пользователь нажимает кнопку удаления элемента в древовидном элементе управления.
  2. Этот конкретный элемент управления вызывает событие удаления элемента с метаданными элемента на уровне страницы (вызовы pageController.raise(...)).
  3. Контроллер страницы загружает элемент управления подтверждением удаления (ну, этот не будет инициировать Ajax-запрос, так как ему не нужно получать данные сервера)
  4. Затем контроллер страницы отправляет событие удаления элемента в этот загруженный / созданный элемент управления
  5. Затем пользователь взаимодействует с ним и подтверждает удаление.
  6. Контроль обеспечивает удаление элементов на сервере (запрос Ajax)
  7. После того, как удаление было завершено, этот элемент управления подтверждением удаления вызывает событие удаленного элемента на уровне страницы.
  8. Контроллер страницы отправляет его всем подписанным элементам управления (в данном случае это будет дерево, главное окно и представление сведений), которые используют это событие, выполняя свои собственные функции (большинство из них удаляло бы элемент из своего списка (необязательно выдавая) запрос Ajax)
  9. После подтверждения подтверждения удаления событие удаленного элемента также уничтожает себя и информирует об этом контроллер страницы, чтобы он знал, что ему придется воссоздать снова, когда будет вызвано определенное событие.

Каковы преимущества использования контроллера страницы?

Контроллер страницы заботится о нескольких вещах:

  • Централизованная обработка страницы «грязное состояние», которую могут использовать все элементы управления - элементы управления могут требовать себя как «грязный», и они также могут проверить, если страница грязная, прежде чем инициировать определенные действия (то есть меню будет проверять грязное состояние перед переходом на новую страницу); Когда элемент управления хотел проинформировать пользователя о том, что страница загрязнена (или лучше сказать, что он не может выполнить требуемое действие), контроллер страницы предоставляет функцию, которая единообразно информирует пользователя о грязном состоянии; Каждый элемент управления (когда требуется грязное состояние) имеет возможность включить строку, описывающую его грязное состояние (т. Е. «Форма изменения элемента должна быть сохранена или отброшена».)
  • Отключение управления при одновременном обеспечении межконтрольного взаимодействия посредством генерации событий и диспетчеризации - органы управления не знают друг друга; только контроллер страницы знает об этих элементах управления и поэтому отвечает за их создание, инициализацию, обработку и удаление событий на уровне страницы;
  • Действия контроллера - аналогично обработчикам событий управления, но они выполняются Контроллер страницы для определенных событий, прежде чем событие будет отправлено получателям (т.е. когда пользователь выбирает элемент, контроллер выполняет действие для создания формы детали на лету, прежде чем отправка события на него - если оно регистрируется для этого события в цикле инициализации);

Как это может быть полезно в вашем случае?

Основная идея здесь заключается в том, что вам нужна развязка управления , которая также централизованно вызывает события (нужен ли вам сложный список событий или просто какой-то простой предопределенный набор зависит от вас и вашего бизнес-процесса). Это позволяет загружать элементы управления асинхронно и независимо взаимодействовать с ними. Контроллер страницы (как я его назвал) позаботится о распределении событий после инициализации элемента управления. Так что это может задержать их до подходящего момента.

Можно ли использовать существующие библиотеки?

О, последняя вещь. Я забыл упомянуть, что мы использовали ExtJS для визуального управления на стороне клиента. Но мы расширили их и написали много собственных. Особенно нам нужна была вся эта интерактивность на уровне страниц. В настоящее время существуют библиотеки javascript, которые могут помочь вам в этом отношении, но я не могу сказать, так как я совершенно незнаком с ними. Но так как их имя применимо, они обеспечивают некоторый контроль на уровне страницы. И это будет Магистраль и JavascriptMVC . Но вы должны проверить, предоставляют ли они соответствующую функциональность или нет.

Приложение - публичные функции контроллера страницы

  • void setDirty(object sender[, string description]) - каждый элемент управления должен вызывать этот метод, когда его состояние было изменено или подвержено изменениям; Описание используется для текстового описания грязного состояния элемента управления и используется при отображении сообщения пользователю (используется в функции isPageDirty)
  • void clearDirty(object sender) - после сохранения или удаления пользователем данных элементы управления должны вызывать этот метод, чтобы позволить другим элементам управления выполнять свои функции »чистой страницы«;
  • bool isPageDirty([bool displayMessage]) - перед тем, как элементы управления выполнят некоторую »функциональность чистой страницы«, они должны вызвать эту функцию; если они предоставляют параметр со значением true, контроллер автоматически отобразит сообщение пользователю (сохранить или удалить), если страница грязная;
  • void createAction(type eventType, enum actionType, function func[, bool runOnce]) - когда вы внедряете новый контроллер, вы готовите себе действия с помощью этой функции;
  • void removeAction(type eventType, enum actionType, function func) - удалит предварительно подготовленное действие;
  • void registerReceiver(type eventType, enum actionType, object receiver, function func) - элементы управления используют эту функцию, чтобы регистрироваться для получения определенных событий;
  • void unregisterReceiver(type eventType, enum actionType, object receiver, function func) - элементы управления должныотмените регистрацию до того, как они будут уничтожены;
  • void raiseEvent(enum actionType, object eventInstance) - элементы управления вызывают этот метод при запуске события на уровне страницы;
  • void initialize() - когда вы наследуете новый контроллер страницы из класса ControllerBase, вы должны реализовать этот метод. Он будет автоматически вызываться при загрузке страницы; вы должен обычно устанавливать начальное состояние страницы в нем (создать все элементы управления, которые должны быть созданы в начале и т. д.)
1 голос
/ 28 июня 2011

Я бы выбрал опцию класса меню, где регистрируются интересующие элементы управления, и класс просто указывает, когда все зарегистрированные элементы управления загружены (опция увеличения числа, вероятно, правильная).

У вас естьпреимущество в том, что это обеспечивает независимость элементов управления, позволяет добавлять другие элементы управления и т. д., что является важным аспектом того, что вы пытаетесь сделать.

Другая идея, которую, как я полагаю, была рассмотрена илисделано, это только привязка к документу уже.Это означает, что привязки будут доступны только после загрузки всех элементов управления на странице.Есть ли какая-то причина, по которой это не подходит или не работает?

...