使用 clojurescript 部分更改字典

Partial change of dictionary with clojurescript

我尝试用 clojurescript 编写这个 d3.js 的代码 https://bl.ocks.org/d3noob/43a860bc0024792f8803bba8ca0d5ecd 因为我想使用 re-frame 框架。

但是我找不到任何解决方案,因为它有在字典中更改值的过程,例如函数#'collapse。

我有问题。 ClojureScript 可以在字典中写入变化的值吗?

例如

function remove_children (d) {
   if (d.children) {
     d.children = null;
   }
}

family_tree = {
  name: "John",
  children: [
     { name: "Jack",
       children: [
          { name: "Michel"}]},
     { name: "Emily",
       children: [
          { name: "Mike"}]}]
};

jack = family_tree.children[0]
remove_children(jack)
;; in clojurescript ... I have no solution ...

如上所述,如果您尝试使用可变数据(对于 D3)和不可变数据(对于 re-frame),您以后可能 运行 会遇到问题。

尽可能使用 ClojureScript 自己的数据结构,并且在与库交互时仅传递 JavaScript 个对象,例如。您可以使用 (clj->js my-map)convert a CLJS map into a JS object

如果你想使用 JS 互操作来改变 JavaScript 个对象,那也是可能的:

(def family-tree
  (clj->js
    {
      "name" "John",
      "children" [
         { "name" "Jack",
           "children" [
              { "name" "Michel"}]},
         { "name" "Emily",
           "children" [
              { "name" "Mike"}]}]
    }))

;; Check if family-tree looks like expected:

cljs.user=> family-tree
#js {:name "John",
     :children #js [#js {:name "Jack",
                         :children #js [#js {:name "Michel"}]}
                    #js {:name "Emily",
                         :children #js [#js {:name "Mike"}]}]}

;; Define remove-children and Jack using interop:

(defn remove-children [elem]
  (set! (.-children elem) nil))

(def jack
  (-> family-tree .-children (get 0)))

;; Test them

cljs.user=> (remove-children jack)
nil

cljs.user=> family-tree
#js {:name "John",
     :children #js [#js {:name "Jack", :children nil} ;; <== Children were deleted
                    #js {:name "Emily",
                         :children #js [#js {:name "Mike"}]}]}