Использование протокола 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))
)
С помощью функции, определенной выше, я могу получить доступ к функциям. Интересно, это правильный подход?
РЕДАКТИРОВАТЬ 2: Хорошо, с дальнейшим анализом сгенерированного кода 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!!!
1 ответ
Похоже, вы ответили на свой вопрос, но на случай, если кто-нибудь окажется здесь...
Методы протокола автоматически переводятся в пространство имен, в котором они объявлены, это означает, что если вы хотите вызывать те функции, которые вы вызываете, как если бы они были обычными функциями в пространстве имен.