【问题标题】:ClojureScript function is always executedClojureScript 函数总是被执行
【发布时间】:2017-10-14 22:34:16
【问题描述】:

我正在学习 ClojureScript,我有两个函数可以改变“root-app” div 中的内容:

(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 中一切正常,因为该页面中存在“root-app” div,但在http://localhost:3000/blog 中,我收到错误消息:

因为该页面中没有这样的 div。这一切都很奇怪,因为看起来 ClojureScript 实际上发现:

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

实际上是 false 并且未打印 console.log。

我的问题是:为什么函数 mount-components 运行并发送错误消息,即使条件 if 为假?奇怪的是console.log:

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

不运行,但 mount-components 功能可以运行。我想我不理解 ClojureScript 工作方式的“序列”。

【问题讨论】:

  • 显然content 为空。元素 ID 对吗?这基本上是一个 NPE。
  • let 替换为when-let 以仅在找到元素时运行。见clojuredocs.org/clojure.core/when-let
  • 你(几乎)永远不应该在函数范围内使用def,你在init!函数中这样做。 def 在全局范围内创建一个 var。请改用 let 的本地绑定。
  • 也应该是“Willkommen zu meim ekelhaften Blog”

标签: clojure clojurescript luminus


【解决方案1】:

我不确定,但是根据您的描述,我认为您正在考虑的逻辑和您实际测试的逻辑并不相同。您的 if 语句在 URL 中查找单词“about”。如果它在那里,那么它会打印控制台日志,即它将在那里为http://localhost:300/about。如果它不存在,它将运行 mount-components 函数,该函数会查找您所说的未包含在页面上的 div ID,因此您会收到错误消息。 mount-components 是一个 ELSE 语句,因此在测试为假时执行。

【讨论】:

    【解决方案2】:

    if 表单的工作方式与 (if cond true-branch false-branch) 类似,因此您的 (mount-component) 会被执行,因为它位于 false 分支中。查看when,它只有一个真正的分支。

    【讨论】:

    • 这就是答案。 if 语句每个分支只需要 1 个表达式,没有隐含的 do。如果你想有条件地做多件事,那么你应该使用when(有一个隐含的do)或将多个语句包装在do
    猜你喜欢
    • 2020-06-05
    • 2016-01-31
    • 1970-01-01
    • 1970-01-01
    • 2021-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多