Понимание запросов Om и состава пользовательского интерфейса

Я пытался обернуть голову вокруг вопросов. Допустим, я хочу Root компонент с несколькими табличными представлениями на нем.

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

Но это очень простой случай. В нетривиальном приложении, вероятно, вы хотели бы иметь TableView с запросом, поскольку вниз по дереву пользовательского интерфейса у вас может быть некоторая сложная структура компонентов пользовательского интерфейса - верхний колонтитул таблицы, нижний колонтитул, строки, ячейки и т. д. Теперь в этом руководстве предлагается подход с запросом:

И все же это все еще несколько упрощенный пример. Так скажем, если у меня есть:

(defmethod read :numbers/odd [_ _ _]
  {:value (filter odd? (range 50))})

(defmethod read :numbers/even [_ _ _]
  {:value (filter even? (range 50))})

в реальном приложении, конечно, данные будут поступать из серверной части, а Ом будет вставлять их в атом состояния (как обычно)

теперь мне нужно иметь TableView компонент с запросом, который может визуализировать любой из них (или любую последовательность в этом случае). Итак, вы видите, я должен как-то рассказать TableView компонент для использования данных, которые находятся где-то еще в атоме состояния. И запрос для TableView должно быть "динамическим", поэтому я могу использовать несколько TableViews рендеринг разных данных.

Допустим, у нас будет что-то вроде этого для Root:

(defui Root
    (query [_] [{:table/odd ,,,} {:table/even ,,,}])
    (render
      [this]
      (let [{:keys [table/odd table/even]}]
        (html [:div
              [:div.odds (ui-table-view odd)]
              [:div.evens (ui-table-view even)]]))))

для пивоварения я опустил интерфейсы Om.Next

Теперь у меня есть несколько вопросов:

  • Как следует запросить для Root выглядит как?
  • Должен ли я иметь параметризованный запрос в TableView (где я мог бы указать ключ для данных в атоме состояния)? Или как еще я могу сказать одно TableView использовать :numbers/odd а другой использовать :numbers/even?
  • Если я использую параметризованный запрос в TableView тогда как мне передать параметры от Root в TableView?
  • Может быть, я должен передать данные или ссылку на данные TableView через вычисленные реквизиты?
  • Как бы я использовал тогда om/get-query (если подзапрос параметризован)?
  • Как бы выглядели методы чтения? Нужно ли "перемещать вещи" в атоме в read? Не похоже на хорошую идею

Может кто-нибудь, пожалуйста, покажите мне какой-нибудь пример. Большое спасибо!.

1 ответ

Решение

Вот что я придумала:

Для каждой таблицы сохраните связанный с ней ключ данных, а затем на этапе чтения получите эти данные и сопоставьте их с картой, представляющей таблицу:

Итак, если у нас есть пара таблиц (с нечетными и четными числами):

    {:app/tables
    [{:id       0
      :title    "Odd numbers"
      :data-key :data/odds}
      {:id       1
      :title    "Even numbers"
      :data-key :data/evens}]}

Этот метод чтения выглядит так:

    (defmethod parsing/read :app/tables
      [{:keys [state parser] :as env} k _]
      (let [ts                (get @state k)
            merge-table-data' (fn [{:keys [data-key] :as t}]
                                (assoc t :table/data
                                      (->> data-key
                                           vector
                                           (parser env)
                                           vals
                                           flatten)))]
        {:value (map merge-table-data' ts)}))

У этого подхода есть один большой недостаток - он будет пытаться проанализировать ВСЕ данные для всех таблиц, поэтому мне нужно найти способ его улучшить - я хочу иметь возможность выборочно указывать таблицы для сбора данных.

Фрагмент для всего решения здесь:

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

upd2: Видимо, этот подход как-то ломает мутации. Идея, тем не менее, правильна - нужно использовать механику нормализации Om.Next. Я постараюсь обновить суть позже.

Другие вопросы по тегам