Проблема в приложении Clojurescript при изменении строк класса - PullRequest
0 голосов
/ 05 августа 2020

У меня странная проблема с частью Clojurescript в моем приложении. Я вытащил все необходимые части в небольшое приложение Leiningen Reagent. Вот соответствующий Иккинг:

(defn current-page []
  (fn []
    (let [page (:current-page (session/get :route))]
      [:div
      [:table {:width "100%"}
        [:tbody
          [:tr {:class "row"}
            [:td "A"] [:td "B"] [:td "C"]]
          [:tr {:class "row"}
            [:td "A"] [:td "B"] [:td "C"]]
          [:tr {:class "row"}
            [:td "A"] [:td "B"] [:td "C"]]
          [:tr {:class "row"}
            [:td "A"] [:td "B"] [:td "C"]]
          [:tr {:class "row"}
            [:td "A"] [:td "B"] [:td "C"]]
          [:tr {:class "row"}
            [:td "A"] [:td "B"] [:td "C"]]                                                            
          [:tr {:class "row"}
            [:td "A"] [:td "B"] [:td "C"]]]]
      [:div {:onClick #(unselect-all-rows)} "Unselect All Rows..."]       
      [:div {:onClick #(select-all-rows)} "Select All Rows..."] ])))

Это просто HTML таблица. Вот функции select и unselect:

(defn unselect-all-rows []
  (prn "Unselecting all.")
  (let [selected-rows (.getElementsByClassName js/document "row-selected")]
    (prn (str "Rows selected: " (.-length selected-rows)))
    (doall (map #(.remove (.-classList %) "row-selected") (array-seq selected-rows)))))

(defn select-all-rows []
  (prn "Selecting all.")
  (let [selectable-rows (.getElementsByClassName js/document "row")]
    (doall (map #(.add (.-classList %) "row-selected") (array-seq selectable-rows))))) 

Функция select-all-rows работает должным образом, ко всем строкам применяется класс «выбрано строкой», а CSS выделяет строки:

enter image description here

But when I execute the unselect-all-rows function I only get SOME of the rows unselected:

enter image description here

If I click 2 more times then all the rows end up unselected. If I look at the console the number of rows being selected is what I expect, 7 in the first case, but it only seems to perform the remove operation on alternating rows:

введите описание изображения здесь

Что мне здесь не хватает?

1 Ответ

1 голос
/ 06 августа 2020

При использовании reagent или любой другой оболочки react ваша функция просмотра - единственное, что должно изменять DOM. В противном случае вы сами не делаете никаких прямых манипуляций с DOM. Таким образом, вы должны фиксировать состояние выбранных строк где-нибудь (либо локальный атом, либо какое-либо другое управляемое состояние, например, re-frame).

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

(defn current-page []
  (let [toggle-ref (r/atom false)
        select-all #(reset! toggle-ref true)
        deselect-all #(reset! toggle-ref false)]
    (fn []
      (let [page (:current-page (session/get :route))
            row-class (if @toggle-ref "row-selected" "row")]
        [:div
         [:table {:width "100%"}
          [:tbody
           [:tr {:class row-class}
            [:td "A"] [:td "B"] [:td "C"]]
           [:tr {:class row-class}
            [:td "A"] [:td "B"] [:td "C"]]
           [:tr {:class row-class}
            [:td "A"] [:td "B"] [:td "C"]]
           [:tr {:class row-class}
            [:td "A"] [:td "B"] [:td "C"]]
           [:tr {:class row-class}
            [:td "A"] [:td "B"] [:td "C"]]
           [:tr {:class row-class}
            [:td "A"] [:td "B"] [:td "C"]]
           [:tr {:class row-class}
            [:td "A"] [:td "B"] [:td "C"]]]]
         [:div {:onClick deselect-all} "Unselect All Rows..."]
         [:div {:onClick select-all} "Select All Rows..."]]))))

Я на самом деле не тестировал этот код, и на самом деле вы, вероятно, захотите сохранить, какие строки действительно выбраны, но это должно дать вам представление о том, как это должно работать.

...