测试 Clojure Om Next 组件是否满足?协议

Test if Clojure Om Next component satisfies? a protocol

在 Clojure(不是 ClojureScript)中,如何检查给定组件是否实现了协议?

(defui MyComp
  static my-protocol
  (aaa [this] []))

(satisfies? my-protocol MyComp) ;; false
(satisfies? om.next.protocols/IReactChildren MyComp) ;; false
;; but
(.aaa ( MyComp nil nil nil nil)) ;; []

据我所知,om.next 不直接支持此功能,因为 defui 的行为与 defrecord 不完全相同。

一种方法(由 untangled 使用)是将协议的实现放在 metadata 中。与 tony kay 的对话:

tony.kay [6:02 PM] So defui in clj land adds the "protocol" things to metadata just a sec... https://github.com/untangled-web/untangled-client/blob/0b2fdfec1f0dde2d1d95b5a4d092131ca6fdc8f4/src/untangled/client/core.cljc#L90-L96 this is why we need functions like get-initial-state. We can call the protocol ones in cljs, but not in clj because js allows his macro to hack them into place Om components have to be stock React components for interop, so we don't actually use protocols per-se, just emulate the syntax this is part of the cleanup work that we need to comb over in a lot of our docs/guide for sever-side rendering. You cannot, for example, call initial-state in your UI and expect clj-land to like it but many of our examples were written before it existed, and are now technically wrong if you want to do ss rendering

这也是 om.next 服务器端渲染的方式。

在om-csshttps://github.com/ladderlife/om-css/blob/dd19235dabca74db1669504fff941ff97abddcc4/src/main/om_css/core.cljc#L240-L242

中也可以看到

不幸的是,由于这些方法需要覆盖 defui,所以它们不能很好地组合在一起。