首先尝试使用ClojureScript中的协议。以下是协议定义/实现:
(defprotocol IDataTable
(-pages [this])
(-cnt! [this cnt])
(-paginate [this])
)
(deftype DataTable [id url info]
IDataTable
(-cnt! [_ cnt] (swap! info (fn [v] (assoc v :cnt cnt))) )
(-pages [_]
(inc (.round js/Math (/ (:cnt @info) (:length @info))))
)
(-paginate [_]
(let [arr (take 5 (drop (- (:page @info) 1) (range 1 (pages))))]
(c/paging id (flatten ["Prev" arr "Next"]) )
))
)
我对如何调用协议中定义的函数感到困惑。
以下是实例化的代码:
(def table-id "some-table")
(def paging (atom {:page 1 :length 10 :cnt 0 }))
(def data-table (DataTable. table-id "/list/data" paging))
以上代码有效,可以使用以下格式访问属性:
(js/alert (.-id data-table))
我面临的问题是如何调用协议中定义的函数。以下表单导致错误(运行时)。
(-cnt! data-table 10) ;; Error: -cnt! is not a method
(.-cnt! data-table 10) ;; Error
浏览生成的Javascript代码,它为函数提供了冗长的名称。
由于
编辑:想想我找到了答案。看起来我需要命名空间中的支持功能。(defn cnt! [t cnt]
(when (satisfies? IDataTable t)
(-cnt! t cnt))
)
使用上面定义的功能,我可以访问这些功能。不知道这是否是正确的方法?
EDIT2:嗯,通过进一步分析生成的javascript代码实现了一个不需要辅助函数的上述编辑,函数调用需要以命名空间为前缀:
(:require [table :as tbl])
(def table-id "some-table")
(def paging (atom {:page 1 :length 10 :cnt 0 }))
(def data-table (DataTable. table-id "/list/data" paging))
(tbl/-cnt! data-table 10) ;; Works!!!
答案 0 :(得分:4)
看起来你回答了自己的问题,但万一有人到此为止......
协议方法会自动提升到声明它们的命名空间,这意味着如果要调用那些调用它们的函数,就好像它们是命名空间中的常规函数一样。