使用defprotocol创建javascript对象

时间:2022-11-13 01:21:55

Given I've defined a protocol

鉴于我已经定义了一个协议

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

And I am interacting with a library in which a javascript object with this interface is passed in as follows

我正在与一个库进行交互,其中传递带有此接口的javascript对象,如下所示

(js/somelib.connect url listener)

Is there an easy way to create a javascript object using the defined protocol?

有没有一种简单的方法来使用定义的协议创建一个javascript对象?

I have tried to reify the protocol:

我试图通过协议来实现:

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

However this does not give an object that is compatible with external libraries.

但是,这不会提供与外部库兼容的对象。

Thanks

1 个解决方案

#1


There is a conceptual mismatch here. The js library already expects a defined behavior but you want to define it yourself from cljs. Should the listener be a js object with 2 methods, onConnection and onUpdate? Then you need some translator between your SubscriptionListener in cljs and a regular object in js:

这里存在概念上的不匹配。 js库已经预期了一个已定义的行为,但你想自己从cljs定义它。听众应该是一个带有2个方法的ons,onConnection和onUpdate吗?然后你需要在cljs中的SubscriptionListener和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))))

Notice that the functions in SubscriptionListener take the object that complies with the protocol as their first argument. If cid is some id given to you by the server and you tried to call (on-connection cid) you would get Method on-connection not defined for integers.

请注意,SubscriptionListener中的函数将符合协议的对象作为其第一个参数。如果cid是服务器给你的一些id并且你试图调用(on-connection cid),那么你将得到没有为整数定义的Method on-connection。

#1


There is a conceptual mismatch here. The js library already expects a defined behavior but you want to define it yourself from cljs. Should the listener be a js object with 2 methods, onConnection and onUpdate? Then you need some translator between your SubscriptionListener in cljs and a regular object in js:

这里存在概念上的不匹配。 js库已经预期了一个已定义的行为,但你想自己从cljs定义它。听众应该是一个带有2个方法的ons,onConnection和onUpdate吗?然后你需要在cljs中的SubscriptionListener和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))))

Notice that the functions in SubscriptionListener take the object that complies with the protocol as their first argument. If cid is some id given to you by the server and you tried to call (on-connection cid) you would get Method on-connection not defined for integers.

请注意,SubscriptionListener中的函数将符合协议的对象作为其第一个参数。如果cid是服务器给你的一些id并且你试图调用(on-connection cid),那么你将得到没有为整数定义的Method on-connection。