Използване на 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 обект с 2 метода, 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