MobX хранит определения в реальном приложении

В этом посте показана сторона Управление состоянием на timefic.com, что означает, что мы не говорим здесь о компонентах React, рендеринге в dom или обработке пользовательских событий. Речь пойдет о том, как организовать данные (состояние) и как смоделировать любое приложение на основе трех типов или семейств магазинов:

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

Итак, в этой статье мы рассмотрим магазины доменов!

Прежде чем продолжить чтение, обратите внимание: этот пост не касается каких-либо общих или архитектурных концепций или конкретных примеров кодирования. Его цель - показать реальный случай, как определяются магазины для решения «проблемы встреч», потому что я думаю, вы можете найти некоторые сходства с той работой, которую вы выполняете.

Хочу отметить, что:

Примеры из реального мира находят лучшие места в вашем мозгу, чтобы оставаться на месте.

Таким образом, в этом сообщении не будет найдено ни foo / bar, ни списка медведей, ни других общих примеров. Вы найдете настоящие ингредиенты для приложения Meetings!

PeopleStore

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

  • UserPicURL: URL-адрес изображения, активного пользователя.
  • IsContact: если пользователь является контактом моего пользователя.
  • IsActive: если учетная запись пользователя активна.

А также для удобства создадим внутри магазина поле myUser с пользователем, который в данный момент подключен.

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

ТегиМагазин

В timefic Теги используются для создания структуры встреч, например, проекта или области, которой принадлежит встреча. Таким образом, это хранилище довольно прямолинейно, но, поскольку существует 2 уровня тегов во времени (проект / тема или область / подобласть), это хранилище фактически служит также для «сглаживания» иерархии и в результате имеет запись с родительским элементом. название области прикреплено к ребенку.

ВстречиМагазин

Основное хранилище модуля (на самом деле модуль имеет то же имя), а также основная коллекция всего приложения.

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

Таким образом, это хранилище должно оставаться простым, быть скелетом вашего приложения и хранить такие данные:

  • Теги: мы добавляем имя и идентификатор тега (тема собрания) и parentTag (проект с этой темой), поэтому мы можем отображать оба имени позже в пользовательском интерфейсе.
  • LogoURL: логотип, который будет отображаться через несколько минут.
  • DateTimeRange: вычисляемое поле для указания дат, когда собрание должно начинаться и заканчиваться: startDate плюс duration.

Взносы

Вклады представляют собой примечания в форме текста, которые участники могут отправить секретарю собрания для включения в протокол. Когда участник публикует свой вклад, секретарь получает уведомление с именем и фотографией участника. Итак, мы берем эту информацию из PeopleStore и прикрепляем к публикации, чтобы ее было легко использовать позже:

  • Автор: Имя, изображение и инициалы человека, сделавшего взнос.
  • OwnContributions: фильтр для вкладов собрания, который показывает только те вклады, которые созданы моим пользователем и еще не опубликованы (их все еще можно изменить).
  • ReceivedContributions: фильтр для вкладов собрания, который показывает только вклады, отправленные моему пользователю и еще не использованные (после публикации они отфильтровываются из этой коллекции).

Презентации Магазин

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

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

Например, изображение будет отображаться внутри тега img, но документ Google или Office будет заканчиваться внутри iframe с URL-адресом, который также включает службу, используемую для отображения это содержание.

Пользователи

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

  • _id, имя, адрес электронной почты, инициалы, activePic, isRegistered, цвет, роль, isMe, askTheFloorCount, hasAskedTheFloor, isChatOn, isMicOn, isVideoOn, isOnline, оценка, токен, isPresenter, isSecretary, peerUID.

Это центральное хранилище для приложения, которое также служит цели определения коллекций или подмножеств элементов для:

  • Активный докладчик, Активный демонстратор экрана, Все активные участники, Я и Организатор.

ЧасыМагазин

В timefic часы играют центральную роль в том, чтобы встреча была продуктивной. Таким образом, собрание должно начинаться вовремя, каждая тема также должна начинаться и заканчиваться вовремя, а также есть время, чтобы закрыть собрание после его завершения (и отправить протокол участникам).

Эти правила основаны на определенных конфигурациях, которые поступают из MeetingsStore, и используются внутри других магазинов для улучшения своих бизнес-правил (например, ActionsStore, AgreementsStore и TopicsStore).

Следующие поля создаются и повторно оцениваются после каждой секунды или «тика» на часах:

  • SecondsToStart - количество секунд до начала встречи.
  • SecondsToSuspend: пора начать, мы не будем ждать больше this секунд ...
  • SecondsElapsed или общее количество секунд с начала встречи.
  • SecondsToFinish - количество секунд до завершения встречи.
  • SecondsToSecretaryClose, или секунды, оставшиеся секретарю для доставки протокола организатору.
  • SecondsToClose, или секунды, которые остаются у организатора для закрытия встречи и отправки минут.

ТемыМагазин

Еще один центральный магазин в приложении. Тема похожа на «мини-встречу», потому что для нее определено время начала, общее время до конца, заметки и т. Д.

Вот некоторые элементы, принадлежащие этому магазину, которые мы только упомянем, по крайней мере, для целей этой публикации:

  • Связанные с пользовательским интерфейсом: myTopics, myActiveTopic, newTopicObject, myMeetingAgenda, myTopicsChatSelector,
  • По времени: secondsRemainingInActiveTopic, secondsElapsedInActiveTopic, activeTopicProgress, extendedSecondsConsumed и meetingAgendaTimer.

ДействияМагазин, Магазин соглашений, Магазин комментариев и Магазин сообщений

Эти хранилища (плюс заметки внутри TopicsStore) являются «хранилищами результатов» или хранилищами, в которых хранится информация, созданная пользователями во время встречи, которая будет в протоколах или другой цифровой форме, доступной после встреча заканчивается.

Они концептуально похожи, но содержат разные данные и бизнес-правила. Я не собираюсь вдаваться в подробности об этих магазинах, но здесь у вас есть некоторые поля, которые у них были:

  • ActionsStore: myActions, newActionObject, mySelectedAction, mySelectablePeople, mySelectableDays, mySelectableHours, myAssignedActions.
  • AgreementStore: myAgreements, newAgreementObject, myAgreementsDisplayedInForm, mySelectedAgreement, myOpenedAgreement, secondsRemainingInAgreement.
  • Магазин комментариев: myComments, myComment, membersComments, unreadedCommentsCount.
  • MessagesStore: myMessages, myActiveTopicMessages, unreadedMessagesCount.

Заключительные слова

Когда вы проектируете свои магазины, вы хотите, чтобы они были:

  • Структурно схожи, хотя они содержат разные данные, все примитивы для определения хранилища остаются такими же: у вас будут примитивные (наблюдаемые) значения, производные (вычисленные) значения, действия по изменению наблюдаемых и реакции для захвата события, которые тоже нужно отразить в данных магазина.
  • Семантически разделены, по возможности избегайте смешивания доменов. Чистый домен должен представлять объект в вашей модели (например, действия, соглашения, комментарии и т. Д.) Или какой-то канал, по которому поступают данные (например, часы и предупреждения), или составное хранилище, которое должно смешивать концепции для представления бизнес-правил.
  • Атомарно разделен или разделен на части, которые «не могут быть разделены дальше», поэтому вы вынуждены дать этой части имя и тем самым разъяснить всем остальным (другим магазинам) цель каждый элемент.

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

Приветствия из Чили 🇨🇱!