Я хочу изменить видимость таблицы при нажатии кнопки, используя взаимодействие clojurescript/javascript.
я пробовал
{:on-click #(-> js/document
(.getElementById "db-search-result-tables")
(.-style)
(.-display "block"))}
Это тег div, который я вызываю.
[:div {:style {
:display "none"}
:id "db-search-result-tables"
:class "db-search-results-table"}
[table-to-display]
я тоже пробовал
(-> js/document
(.getElementById "db-search-result-tables")
(.-style)
(.-display)
(set! ""))
но он отображает таблицу только на мгновение, а затем снова устанавливает для отображения значение none.
Я использую реагент и рефрейминг. Спасибо за ссылки на некоторые примеры.
Я добавил ответ, относящийся к рефреймингу, надеюсь, он будет полезен.
Да, я обнаружил, что конкретный ответ на рефрейминг помог мне сделать именно то, на что я надеялся. Помещение нужной таблицы в «текущее представление таблицы» в базе данных приложения и ее сброс каждый раз, когда я нажимал новую кнопку, чтобы показать другую таблицу, было действительно полезно. @NotsoVeteran
РЕДАКТИРОВАТЬ: это решение не предполагает наличия какой-либо библиотеки, основываясь на чтении, что в постановке задачи явно не упоминается какая-либо библиотека/фреймворк, только взаимодействие JS, непосредственное изменение DOM а-ля jQuery. Не используйте этот ответ, если вы используете любую библиотеку или любую оболочку React, такую как реагент.
Может быть, было бы проще создать вспомогательную функцию, скажем, toggle
, которая скрывает/показывает отображение данного элемента по его идентификатору?
(ns myproject.core)
(defn ^:export toggle [elem-id]
(let [elem (js/document.getElementById elem-id)
style (.-style elem)
display (.-display style)
new-display (if (= "none" display) "block" "none")]
(set! (.-display style) new-display)))
Мы находим элемент по его идентификатору, используем переменную для получения текущего стиля, получаем отображение из стиля и вычисляем новое значение для атрибута отображения, а затем set!
возвращаем его обратно в отображение.
Я использовал тег метаданных ^:export
, чтобы функцию можно было вызывать прямо из документа, например:
<div>
<button onClick = "myproject.core.toggle('details')">Toggle details</button>
</div>
<div id = "details" style = "display: none">
Some details here. Some details here. Some details here. Some details here.
</div>
Это решение специфично для рефрейминга. Я бы предложил использовать app-db
для хранения состояния, handler
для изменения состояния и sub
для получения текущего значения. README от Re-frame — отличный ресурс для изучения этой установки: https://github.com/Day8/рефрейм
Прямые изменения в DOM будут переопределены повторным кадрированием, когда оно сочтет нужным (именно поэтому ваш исходный код возвращался к исходному определению компонента).
Вы можете создать handler
следующим образом:
(re-frame.core/reg-event-fx
:handlers/enable-search-results
(fn [{:keys [db]} _]
{:db (assoc db :show-search-results? true})
И sub
для получения значения:
(re-frame.core/reg-sub
:subs/show-search-results?
(fn [db]
(:show-search-results? db))
Теперь обновите кнопку поиска, чтобы отправить на handler
:
[:button
{:on-click #(re-frame.core/dispatch [:handlers/enable-search-results])}
"Click to show search results"]
И обновите раздел результатов поиска, чтобы он был видимым/скрытым на основе sub
:
(let [show-search-results? @(re-frame.core/subscribe [:subs/show-search-results?])]
[:div {:style {:display (if show-search-results? "visible" "none"}
:id "db-search-result-tables"
:class "db-search-results-table"}
[table-to-display]])
В качестве альтернативы:
(let [show-search-results? @(re-frame.core/subscribe [:subs/show-search-results?])]
(when show-search-results?
[:div {:id "db-search-result-tables"
:class "db-search-results-table"}
[table-to-display]]))
Поскольку состояние app-db
является постоянным, именно здесь можно безопасно контролировать подобные «мутации».
Используете ли вы Reagent и/или рефрейминг? (Реагент имеет здесь пример состояния обработки: github.com/реагент-проект/реагент#примеры)