Использование defprotocol для создания объекта javascript

Учитывая, что я определил протокол

(defprotocol SubscriptionListener
  (onConnection [cid] "")
  (onUpdate [cid data] ""))

И я взаимодействую с библиотекой, в которой объект javascript с этим интерфейсом передается следующим образом

(js/somelib.connect url listener)

Есть ли простой способ создать объект javascript с использованием определенного протокола?

Я попытался reify протокол:

(js/somelib.connection "localhost" (reify SubscriptionListener
                                      (onConnection [cid] (println cid))
                                      (onUpdate [cid data] (println data))))

Однако это не дает объект, совместимый с внешними библиотеками.

Спасибо


person Pete    schedule 11.05.2015    source источник


Ответы (1)


Здесь концептуальное несоответствие. Библиотека js уже ожидает определенное поведение, но вы хотите определить его самостоятельно из cljs. Должен ли слушатель быть объектом js с двумя методами, onConnection и onUpdate? Тогда вам нужен переводчик между вашим SubscriptionListener в cljs и обычным объектом в js:

(defprotocol SubscriptionListener
  (on-connection [o cid])
  (on-update     [o cid data]))

(defn translator
  "Translates a cljs object that follows SubscriptionListener 
   into a js object that has the right mehods"
  [o]
  #js {:onConnection (fn [cid]      (on-connection o cid))
       :onUpdate     (fn [cid data] (on-update o cid data))})

(js/somelib.connection "localhost"
                        (translator (reify SubscriptionListener
                                      (on-connection [_ cid] (println cid))
                                      (on-update     [_ cid data] (println data))))

Обратите внимание, что функции в SubscriptionListener принимают объект, соответствующий протоколу, в качестве первого аргумента. Если cid - это какой-то идентификатор, предоставленный вам сервером, и вы попытались вызвать (on-connection cid), вы получите Method on-connection not defined for integers.

person sbensu    schedule 12.05.2015