5

我正在使用 clojure 和 clojurescript 开发 RIA。后端使用打嗝来生成结果 html,比如

(html5 
[:head 
  (include-js "/js/my-cljs-generated.js")]
[:body ... ])

如何在生成的 html 中将 edn(hashmap、vector 等) 传递给 clojurescript,即不进行 ajax 调用?

我想让打嗝做这样的事情:

(include-edn 
   "var_name" {:foo :bar}) ; or any other clojure data

并且能够以某种方式(例如通过名称)从 cljs 访问传递的 edn。

目前我的实现有点hacky并将edn存储在全局js var中

(hiccup/javascript-tag (str "var edn = \""
                       (pr-str my-clojure-data) "\";"))        

并且在 cljs 方面确实喜欢

(jayq/document-ready 
  (fn []
    (if-let [edn (.-edn js/window)]
      (do-something-with (cljs.reader/read-string edn))
    )
    ...
)

也许有更惯用的方式来实现这一目标?

4

3 回答 3

3

你的方法很好。如果您担心手动创建 JavaScript 代码,另一种方法是将pr-str作为数据的结果放在定义明确的元素中。类似于以下内容:

[:div {:style {:display "hidden"}
       :id "server-originated-data"
       :data-var-1 (pr-str var-1)
       :data-var-2 (pr-str var-2)}]

然后,您可以使用以下内容从 ClojureScript 获取该数据:

(defn get-data
  [tag]
  (-> (.getElementById js/document "server-originated-data")
      (.getAttribute (str "data-" tag))
      (cljs.reader/read-string)))

不过,同样,您的方法很好。

于 2014-09-07T17:06:30.350 回答
1

您的“实施”非常好。如果这会让你感觉更舒服,请将其包装在一个函数中:)

如果您发出例如已编译的 ClojureScript,则不会有什么不同;该值仍然是全局且可变的。

于 2013-03-16T20:47:42.227 回答
1

您可以考虑使用推送(基于事件)的方法,而不是拉取:将生成的 edn 数据作为字符串放置在 [:script] 标记内,作为 javascript 调用 clojurescript 函数的参数。当浏览器加载脚本时,它会将 edn 发送到您的处理函数,允许您的应用程序加载它。

这将比您当前的方法更惯用,因为它不需要状态或全局数据,并且如果需要,可以很容易地适应以后使用 ajax。

于 2013-03-27T10:37:12.417 回答