Clojure 如何为试剂组件编写装饰器

Clojure 如何为试剂组件编写装饰器,clojure,decorator,clojurescript,reagent,re-frame,Clojure,Decorator,Clojurescript,Reagent,Re Frame,我有一些类似的试剂成分,它们可以以某些方式呈现给定的数字: (定义普通编号[n] [:h1 n]) (defn饼图[n] (图n) 还有一些(简化的)状态: (def状态(r/atom{:a5:b10:c7})) 我知道如何编写一个组件,该组件可以访问该状态并使用其中一个组件呈现该状态: (def提取和呈现饼图[k] (让[v(得到@state k)] [饼图五]) [取出并呈现馅饼:a];使用5渲染饼图 到目前为止,一切顺利。但这是耦合和重复的 目标是: 一个装饰者就好了,它可以获取一些

我有一些类似的试剂成分,它们可以以某些方式呈现给定的数字:

(定义普通编号[n]
[:h1 n])
(defn饼图[n]
(图n)
还有一些(简化的)状态:

(def状态(r/atom{:a5:b10:c7}))
我知道如何编写一个组件,该组件可以访问该状态并使用其中一个组件呈现该状态:

(def提取和呈现饼图[k]
(让[v(得到@state k)]
[饼图五])
[取出并呈现馅饼:a];使用5渲染饼图
到目前为止,一切顺利。但这是耦合和重复的

目标是: 一个装饰者就好了,它可以获取一些状态并将其传递给孩子们。用法如下所示:

[fetch:a
[饼图]]
可能的解决办法:
(defn fetch[k wrapped]
(让[v(得到@state k)]
(v)
这是可行的,但它弄乱了组件定义的向量,并且它假设了许多包装组件的参数。对于连锁装饰商来说,它失败了



必须有一个聪明而稳健的解决方案。有什么想法吗?

您不能仅仅因为您向装饰组件传递了一个参数而放弃关于装饰组件参数的假设,并且应该知道如何以与函数调用相同的方式进行。但您无需将向量传递给装饰器,只需组件本身即可:

(defn fetch [k component]
  (let [v (get @state k)]
    [component v]))

[fetch :test pie-chart] ; ~ [pie-chart (get @state :test)]
对于链接,您希望为
组件
支持额外的参数:

(defn fetch [k component & args]
  (let [v (get @state k)]
    (into [component v] args)))

(defn prepare [s component & args]
  (let [v (keyword s)]
    (into [component v] args)))

[prepare "test" fetch pie-chart {:colourful true}]
; ~ [pie-chart (get @state (keyword "test")) {:colourful true}]

这有点像HOFs和线程宏。

仅使用试剂,我们可以使用游标

(defn com-a [state]
  (fn []
    [:h1 @state]))

(defn fetch [db]
  (let [state (reagent/cursor db :k)] ; assume {:k "dd"}
    (fn []
      [com-a state])))
带重框

(re-frame/reg-sub
  :chart-data
  (fn [db [_ query]]
    (get-in db query)))

(defn com-a [state]
  (fn []
    [:h1 @state]))

(defn fetch [db]
  (let [state (re-frame/subscribe [:chart-data [:k]])]
    (fn []
      [com-a state])))

这看起来是一个非常有前途和优雅的解决方案。我试试看。非常感谢你。