Функция ClojureScript всегда выполняется

Я изучаю ClojureScript, у меня есть две функции, которые просто изменяют содержимое в div "root-app":

(ns blog.core)

 (defn mount-components []
   (let [content (js/document.getElementById "root-app")]
     (while (.hasChildNodes content)
       (.removeChild content (.-lastChild content)))
     (.appendChild content (js/document.createTextNode "Wilkommen zu mein 
     ekelhaft blog!!"))))

 (defn init! []
   (def current_url js/window.location.href)
   (if (clojure.string/includes? current_url "about")
     (.log js/console (str "Whatever URL ->>>" js/window.location.href))
     (mount-components)))

Все работает нормально в http://localhost:3000/about, потому что в нем существует div "root-app" страницу, но в http://localhost:3000/blog я получаю сообщение об ошибке:

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

Потому что на этой странице нет такого div. Все это странно, потому что похоже, что ClojureScript на самом деле обнаруживает, что:

 (if (clojure.string/includes? current_url "about")

на самом деле ложно, а журнал console.log не печатается.

У меня вопрос: почему функция mount-components запускается и отправляет сообщение об ошибке, даже если условное if ложно? Странно то, что console.log:

 (.log js/console (str "Whatever URL ->>>" js/window.location.href))   

не запускается, но работает функция mount-components. Думаю, я не понимаю «последовательность» в том, как работает ClojureScript.


person aarkerio    schedule 13.10.2017    source источник
comment
Очевидно content имеет значение null. Идентификатор элемента правильный? Это в основном NPE.   -  person Carcigenicate    schedule 13.10.2017
comment
Замените let на when-let, чтобы запускался только при обнаружении элемента. См. clojuredocs.org/clojure.core/when-let.   -  person Oles Savluk    schedule 13.10.2017
comment
Вы (почти) никогда не должны использовать def внутри области действия функции, что вы делаете в функции init!. def создает переменную в глобальной области видимости. Вместо этого используйте локальную привязку с let.   -  person Toni Vanhala    schedule 13.10.2017
comment
Также, вероятно, это должен быть Блог Willkommen zu meim ekelhaften   -  person ClojureMostly    schedule 13.10.2017


Ответы (2)


Я не уверен, но, судя по вашему описанию, я думаю, что логика, о которой вы думаете, и логика, которую вы фактически тестируете, не совпадают. Ваш оператор if ищет в URL-адресе слово «о». Если он есть, то он распечатывает журнал консоли, т.е. он будет там для http: // localhost: 300 / about . Если его НЕТ, он запустит функцию mount-components, которая ищет идентификатор div, который, по вашему мнению, не включен на страницу, поэтому вы получите сообщение об ошибке. mount-components является оператором ELSE и поэтому выполняется, когда тест ложен.

person Tim X    schedule 14.10.2017

Форма if работает так же, как (if cond true-branch false-branch), поэтому ваш (mount-component) выполняется, потому что он находится в ветке false. Посмотрите when, у которого есть только настоящая ветвь.

person heyarne    schedule 14.10.2017
comment
Это ответ. Оператор if принимает только 1 выражение на ветвь, неявного do. Если вы хотите условно выполнить несколько действий, вам следует использовать when (имеет неявное do) или заключить несколько операторов в do - person bfabry; 14.10.2017