Виджеты взаимодействуют с виджетами: я только что закончил создание этого несколько дней назад. Я посмотрел, как вы это реализовали, и вот несколько дополнительных идей для вас.
Созданная вами система push-уведомлений очень похожа на систему событий jQuery DOM, благодаря которой произвольные события могут передаваться и приниматься. Я немного использовал эту систему для разработки разорванных виджетов, однако нашел ее весьма желательной, потому что в конечном итоге «толкает» (события, испускает, что угодно) из контекста - как в слушателях, понятия не имею, если это даже в рамках того, что они хотели, пока они не опросят событие.
Рассмотрим, например, если каждый элемент пользовательского интерфейса на веб-странице был виджетом в вашей системе. Там будет легко 30+ на одной странице. Если каждый из них должен был нажать «загруженное» сообщение, остальные 29 должны его получить. Кроме того, как вы упомянули, сторонние разработчики будут разрабатывать для этой системы. Затем им приходится обременять себя фильтрацией сообщений, которые они не хотят получать.
Подход, который я использовал в своей последней системе связи виджетов, - это то, что я называю подходом "pubstring" / "substring" (и, честно говоря, я уверен, что кто-то еще придумал эту идею до меня и имеет какое-то круто звучащее название для него). По сути, всякий раз, когда виджет «толкает», этот толчок превращается в строку, которая содержит: область (контекст), тип виджета, конкретный идентификатор виджета, каким бы он ни был, и конкретное сообщение.
Так скажем, например, виджет с идентификатором 45, типа «твит-лист», в области «пользовательские» отправляет сообщение «загружен». Строка паба будет тогда отображаться в: custom.tweet-list.45.loaded
.
Когда подписки размещаются, они вводятся через хеш-таблицу, которая может дополнительно содержать значения для 4 атрибутов (вы можете легко добавить больше, кроме имеющейся у меня области / типа / идентификатора / сообщения). Слушание тогда будет таким:
listen({ realm: 'custom', type: 'whatever' }, f); // (where 'f' is a function)
Часть слушателя вашей платформы может превратить эту хеш-таблицу в «подстроку», которая будет регулярным выражением, выражающим фильтры, для которых она представляет:
custom\.whatever\.[^\.]+\.[^\.]+
Это регулярное выражение хранится в виде скомпилированного регулярного выражения в некотором скрытом массиве ...
__subscriptions.push(new RegExp(subString));
Затем всякий раз, когда что-то выдвигается (то есть публикуется), платформа в основном циклически перебирает массив __subscription, запускает .test
каждой сохраненной подстроки (regex) и выполняет обратный вызов для этой подстроки, если совпадает.
Используя эту систему, можно применять неограниченное количество отфильтрованных слушателей, и слушатели знают, что они получают уведомления только в тех контекстах, которые им интересны.
Примеры:
// Listen for all messages by widget ID #99
listen({ id: 99 } ,f);
// Listen for all messages by widgets in realm clientB
listen({ realm: 'clientB' }, f);
// Listen for the data-received push of widgets whose type is tweet-list
listen({ type: 'tweet-list', message: 'data-received' }, f);
Поскольку регулярное выражение на самом деле является просто конкатенацией, оно также может быть включено в фильтр.
// Listen for any data- message
listen({ message: 'data-[^\.]+' }, f);
Прелесть этой системы в том, что вы можете сохранить свой текущий интерфейс, чтобы "все было просто" и просто проверить строку или хэш-таблицу для argument[0]
. Другими словами ..
// This
listen('loaded', f);
// Could be equivalent to this on the backend:
listen({ message: 'loaded' }, f);
Я знаю, что это было долго, но надеюсь, что это дало вам некоторые идеи.