Вы делаете это так же, как в простом замыкании, используя update-in
.Сначала запустите CheatSheet Clojure:
http://jafingerhut.github.io/cheatsheet/clojuredocs/cheatsheet-tiptip-cdocs-summary.html
или версию ClojureScript: http://cljs.info
Посмотрите документы для update-in
: https://clojuredocs.org/clojure.core/update-in
Вам нужно 2 компонента
- Путь для навигации по сайту мутации
- Функция для выполнения мутации с учетом точки из (1) .
Вы не указали свои данные полностью.Я предполагаю, что это выглядит так:
(def db {:questions [
{:33 {:question "one", :id 33,
:answers [{:id 22, :question_id 33, :answer "one", :correct false}
{:id 4, :question_id 33, :answer "two", :correct false}]}},
{:39 {:question "two", :id 39, :answers []}},
{:41 {:question "three", :id 41,
:answers [{:id 29, :question_id 41, :answer "one", :correct false}
{:id 35, :question_id 41, :answer "two", :correct true}]}}]})
Я создам новую карту answer
, чтобы добавить:
(def new-answer {:id 42, :question_id 442, :answer "The Ultimate", :correct false})
Этот код показывает процесс по частям.
(let [submap (get-in db [:questions 0 :33 :answers])
modified (conj submap new-answer)
final-answer (update-in db [:questions 0 :33 :answers] conj new-answer) ]
Сначала навигация, чтобы получить submap
:
submap =>
[{:id 22, :question_id 33, :answer "one", :correct false}
{:id 4, :question_id 33, :answer "two", :correct false}]
И как вы добавляете новый ответ:
modified =>
[{:id 22, :question_id 33, :answer "one", :correct false}
{:id 4, :question_id 33, :answer "two", :correct false}
{:id 42, :question_id 442, :answer "The Ultimate", :correct false}]
И собираем все вместев одну операцию:
final-answer =>
{:questions
[{:33
{:question "one",
:id 33,
:answers
[{:id 22, :question_id 33, :answer "one", :correct false}
{:id 4, :question_id 33, :answer "two", :correct false}
{:id 42, :question_id 442, :answer "The Ultimate", :correct false}]}}
{:39 {:question "two", :id 39, :answers []}}
{:41
{:question "three",
:id 41,
:answers
[{:id 29, :question_id 41, :answer "one", :correct false}
{:id 35, :question_id 41, :answer "two", :correct true}]}}]}
Все это работает идентично в ClojureScript как в Clojure.
Не беспокойтесь об использовании перехватчика path
.Я думаю, что это смущает вещи больше, чем помогает.И не беспокойтесь о скорости рендеринга, если:
- У вас все работает и проверено, и вы знаете, что это правильно.
- Вы измерили скорость рендеринга и можете задокументировать, что естьЗадача и количество, которое необходимо ускорить.
- Для длинных списков вещей посмотрите метаданные
key
, которые вы можете добавить к каждому элементу списка для Реагента.См .: Reagent React Clojurescript Предупреждение: Каждый элемент в seq должен иметь уникальный ключ: ключ
Обновление
Обратите внимание, что submap
и modified
показаны только для демонстрационных целей , чтобы показать, как работает update-in
.Выражение update-in
- это единственное, что вы фактически включили бы в свой код.Также обратите внимание, что update-in
использует только db
и new-answer
.