Taking a first stab at using protocols in ClojureScript. Following is the protocol definition/implementation:
(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"]) )
))
)
I am confused on how to invoke the functions defined in the protocol.
Following is the code to instantiate:
(def table-id "some-table")
(def paging (atom {:page 1 :length 10 :cnt 0 }))
(def data-table (DataTable. table-id "/list/data" paging))
The above code works and can access the properties using the following form:
(js/alert (.-id data-table))
The problem I am facing is how to invoke the functions defined in the protocol. The following forms result in error (runtime).
(-cnt! data-table 10) ;; Error: -cnt! is not a method
(.-cnt! data-table 10) ;; Error
Browsed the generated Javascript code, its got long-winded names for functions.
Thanks
EDIT: Think I found the answer. Looks like I need supporting functions in the namespace.
(defn cnt! [t cnt]
(when (satisfies? IDataTable t)
(-cnt! t cnt))
)
With the function defined above, am able to access the functions. Wonder if this is the right approach?
EDIT2: Well, with further analyzing the generated javascript code realized one doesn't need helper functions as the above edit, the function calls needs to prefixed with namespace:
(: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!!!