Элемент таблицы рендеринга с colspan в Reagent

У меня есть таблица в реагенте, и я установил col-span заголовка таблицы = 2.

 (defn my-table []
  [:table.table.table-striped.table-bordered
   [:thead
    [:tr
     [:th "Col1"]
     [:th "Col2"]
     (doall (for [id @ids]
          ^{:key id}
          [:th {:data-id (id :id)
                :col-span "2"}
           (str (get id :name))]))]]
   [:tbody
    (doall (for [i (range (count @table-items))]
         (let [table-item (cursor table-items [i])]
           ^{:key i}
           [item-row table-item])))]])

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

[:div [:td [:span (:id id)]]
             [:td [:span (:name id)]]]

который, как я знаю, является неправильным/недействительным html.

 (defn item-row [item]
    (fn []
      [:tr
       [:td [:span (:key1 @item)]]
       [:td [:span (:key2 @item)]]
       (doall (for [id @ids]
            ^{:key id}
            [[:td [:span (:x id)]]
             [:td [:span (:y id)]]]))]))

Кто-нибудь знает, как отобразить два элемента :td в цикле for? Моя идея заключалась в том, чтобы обернуть два элемента :td в вектор и позволить реагенту обрабатывать рендеринг разделенных столбцов.

 (doall (for [id @ids]
            ^{:key id}
            [[:td [:span (:x id)]]
             [:td [:span (:y id)]]])

Я также получаю следующую ошибку: core.cljs:4793 Uncaught Error: No item [:td "."] in vector of length 2 at Object.cljs$core$vector_index_out_of_bounds [as vector_index_out_of_bounds]

что коррелирует с [:td [:span (:y id)]]


person Michael Thurmond    schedule 22.03.2018    source источник
comment
Что не работает так, как вы ожидаете? Вы говорите, что HTML, который вы создаете, недействителен?   -  person jmargolisvt    schedule 22.03.2018
comment
Я обновил свой вопрос, чтобы добавить больше деталей   -  person Michael Thurmond    schedule 22.03.2018


Ответы (1)


Вы можете воспользоваться тем фактом, что вы просто возвращаете данные, поэтому один из способов сделать это — просто создать начальное содержимое вектора :tr с этими первыми двумя столбцами, а затем добавить остальные элементы :td с помощью into. Вот пример, который, я думаю, решит вашу проблему:

cljs.user=> (def ids [{:x 1 :y 2} {:x 3 :y 4}])
#'cljs.user/ids
cljs.user=> (let [tr [:tr 
       #_=>           [:td "first col"]
       #_=>           [:td "second col"]]]
       #_=>   (reduce (fn [acc id]
       #_=>             (into acc
       #_=>                   [[:td [:span (:x id)]]
       #_=>                    [:td [:span (:y id)]]]))
       #_=>           tr
       #_=>           ids))
[:tr [:td "first col"] [:td "second col"] [:td [:span 1]] [:td [:span 2]] [:td [:span 3]] [:td [:span 4]]]
cljs.user=> 
person Justin L.    schedule 22.03.2018
comment
Отлично работает, и я это понимаю, но мне любопытно, почему мой подход с использованием for не работает? - person Michael Thurmond; 26.03.2018
comment
Вам понадобится еще один шаг с for, потому что for строит последовательность с одним элементом для каждого id, но вы хотите два элемента для каждого id. Итак, вам нужно взять вывод из for, а затем, возможно, сделать что-то с map и into, чтобы сгладить парные элементы td. - person Justin L.; 27.03.2018