Код не вызывается из блока go, но работает из REPL
У меня есть код, который обновляет DOM. new-recipe!
вызывает API для получения новой строки рецепта. update-recipe-state
Далее обновляет это состояние на экране. Наконец-то у нас есть звонок update-transition-buttons
,
(defn- add-listener-to-recipe-button! []
"Listens to go button, creates a new recipe and displays it"
(create-click-event-listener! (dommy/sel1 :#button-start)
#(go (new-recipe!)
(<! (timeout 2000))
(update-recipe-state!)
(<! (timeout 2000))
(update-transition-buttons! "onboarding"))))
;; define your app data so that it doesn't get over-written on reload
(defonce world
(add-listener-to-recipe-button!))
update-transition-buttons
имеет некоторые задержки между шагами (используя здесь код тайм-аута) выглядит следующим образом:
(defn- update-transition-buttons! [recipe-name]
"Updates the buttons with the transition names"
(go
;; Split response in list of actions by splitting on the comma
(let [response (<! (http/get (get-recipe-transitions-url recipe-name)))
transition-names (clojure.string/split (:body response) ",")]
(go (update-buttons! transition-names)
(<! (timeout 2000))
(js/console.log transition-names)
(set-button-event-handlers! transition-names)))))
Таким образом, это разделяет ответ на строку. updates-buttons
изменяет состояние на странице, добавляя несколько кнопок (это видно). Опять есть тайм-аут, а затем я хочу добавить обработчики событий для кнопок. Вот где это идет не так.
Подпрограмма для создания слушателей событий (которые также содержат console.log
) выглядит следующим образом:
(defn- listen-to-transition-button! [name]
"Creates click event listener on button (button HTML ID should be name)"
(do (js/console.log (str "Listening to " name))
(let [name-without-spaces (clojure.string/replace name " " "")
button (dommy/sel1 (keyword (str "#" name-without-spaces)))
action #(do (perform-action! name)
(update-recipe-state!))]
(create-click-event-listener! button action))))
(defn- set-button-event-handlers! [names]
"Creates click event listeners on the buttons (button ID should be name)"
(map listen-to-transition-button! names))
Снова вы видите console.log
сообщение, которое должно произойти для каждого элемента, который передается. Вывод, который я получаю в консоли Firefox:
[ПЕРВЫЙ ОБСЛУЖИВАНИЕ]
[СЛЕДУЮЩАЯ СЛУЖБА ВЫЗОВА]
[ОТОБРАЗИТЬ СПИСОК ШАГОВ]: ["Step1", "Step2", "Step3"]
Я ожидаю, что это:
[ПЕРВЫЙ ОБСЛУЖИВАНИЕ]
[СЛЕДУЮЩАЯ СЛУЖБА ВЫЗОВА]
[ОТОБРАЗИТЬ СПИСОК ШАГОВ]: ["Step1", "Step2", "Step3"]
Прослушивание Step1
Прослушивание Step2
Прослушивание шага 3
Поэтому обработчики событий (которые зависят от HTML, сгенерированного на предыдущем шаге) по какой-то причине не добавляются, и console.log
сообщение не отображается.
Когда я вызываю тот же код из REPL, я вижу вывод, то есть:
repl => (set-button-event-handlers! ["Step1", "Step2", "Step3"])
(#object [Объект [объект Object]] #object[Объект [объект Object]] #object[Объект [объект Object]])
И вывод консоли:
Прослушивание Step1
Прослушивание Step2
Прослушивание шага 3
Почему может set-button-event-handlers!
быть вызванным из REPL, но не в update-transition-buttons
метод после update-buttons
?
1 ответ
Похоже, проблема здесь:
(map listen-to-transition-button! names)
в set-button-event-handlers!
он создает ленивый seq, и элементы не будут реализованы до тех пор, пока они не будут использованы где-то в коде (что никогда не происходит), но когда вы вызываете его в repl, полностью реализуется, чтобы показать все элементы в выводе. Попробуйте изменить эту строку на:
(doall (map listen-to-transition-button! names))