2012-07-10 43 views
2

首先在ClojureScript中使用協議。以下是協議定義/實現: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!!! 

回答

4

看起來你回答了你自己問題,但萬一任何人在這裏結束...

協議方法會自動提升到它們聲明的名稱空間,這意味着如果你想調用這些函數,你可以調用它們,就好像它們是函數中的常規函數​​一樣命名空間。

+0

如果你想知道更多關於clojurescript的協議:http://blog.klipse.tech/clojurescript/2016/04/09/clojurescript-protocols-secret.html – 2016-04-10 14:49:12