First stab at ref support

This commit is contained in:
Dan Holmsand 2014-02-15 11:03:24 +01:00
parent b2bfc14afb
commit 305fc73d8a
3 changed files with 64 additions and 7 deletions

View File

@ -103,6 +103,14 @@ Everything is optional, except :render.
[this] [this]
(.getDOMNode this)) (.getDOMNode this))
(defn ref [parent ref child]
(assert (util/reagent-component? parent))
(assert (keyword? ref) (str "Ref must be a keyword, not " (pr-str ref)))
(tmpl/make-ref-component parent ref child))
(defn refs [this]
(assert (util/reagent-component? this))
(tmpl/get-refs this))
(defn merge-props (defn merge-props

View File

@ -113,8 +113,10 @@
(def dont-wrap #{:cljsRender :render :componentFunction}) (def dont-wrap #{:cljsRender :render :componentFunction})
(defn dont-bind [f] (defn dont-bind [f]
(doto f (if (ifn? f)
(aset "__reactDontBind" true))) (doto f
(aset "__reactDontBind" true))
f))
(defn get-wrapper [key f name] (defn get-wrapper [key f name]
(if (dont-wrap key) (if (dont-wrap key)

View File

@ -18,6 +18,7 @@
:for "htmlFor" :for "htmlFor"
:charset "charSet"}) :charset "charSet"})
;;; Common utilities ;;; Common utilities
(defn hiccup-tag? [x] (defn hiccup-tag? [x]
@ -47,6 +48,7 @@
(or (attr-aliases n) (or (attr-aliases n)
(util/dash-to-camel n))) (util/dash-to-camel n)))
;;; Props conversion ;;; Props conversion
(def cached-prop-name (memoize undash-prop-name)) (def cached-prop-name (memoize undash-prop-name))
@ -84,6 +86,7 @@
(set-id-class objprops id-class)) (set-id-class objprops id-class))
objprops))) objprops)))
;;; Specialization for input components ;;; Specialization for input components
(defn input-initial-state [this] (defn input-initial-state [this]
@ -115,6 +118,7 @@
(def input-components #{(aget DOM "input") (def input-components #{(aget DOM "input")
(aget DOM "textarea")}) (aget DOM "textarea")})
;;; Wrapping of native components ;;; Wrapping of native components
(declare as-component) (declare as-component)
@ -150,8 +154,6 @@
(aset "componentWillReceiveProps" (aset "componentWillReceiveProps"
#(this-as C (input-will-receive-props C %))))) #(this-as C (input-will-receive-props C %)))))
;;; Conversion from Hiccup forms
(defn wrap-component [comp extras name] (defn wrap-component [comp extras name]
(let [input? (input-components comp) (let [input? (input-components comp)
input-setup (if input? input-render-setup) input-setup (if input? input-render-setup)
@ -164,6 +166,54 @@
(add-input-methods spec)) (add-input-methods spec))
(.createClass React spec))) (.createClass React spec)))
(defn create-class [spec]
(comp/create-class spec as-component))
;;; Ref support
(def cljs-refs "cljsRefs")
(defn update-ref [this]
(let [rd (-> this util/get-props :ref-data)
{:keys [parent ref]} rd
refed (-> this (aget "refs") (aget (name ref)))]
(aset parent cljs-refs
(-> (aget parent cljs-refs)
(assoc (keyword ref) refed)))))
(def ref-component
(create-class
{:displayName "ref-component"
:component-did-mount update-ref
:component-did-update update-ref
:component-will-unmount
(fn [this]
(let [rd (-> this util/get-props :ref-data)
{:keys [parent ref]} rd
refed (-> this (aget "refs") (aget (name ref)))]
(aset parent cljs-refs
(-> (aget parent cljs-refs)
(dissoc (keyword ref))))))
:render
(fn [this]
(let [rd (-> this util/get-props :ref-data)
{:keys [parent ref child]} rd
react-comp (as-component child)]
(-> react-comp (aget "props") (aset "ref" (name ref)))
react-comp))}))
(defn make-ref-component [parent ref child]
[ref-component {:ref-data {:parent parent
:ref ref
:child child}}])
(defn get-refs [this]
(aget this cljs-refs))
;;; Conversion from Hiccup forms
(defn parse-tag [hiccup-tag] (defn parse-tag [hiccup-tag]
(let [[tag id class] (->> hiccup-tag name (re-matches re-tag) next) (let [[tag id class] (->> hiccup-tag name (re-matches re-tag) next)
comp (aget DOM tag) comp (aget DOM tag)
@ -179,9 +229,6 @@
(def cached-wrapper (memoize get-wrapper)) (def cached-wrapper (memoize get-wrapper))
(defn create-class [spec]
(comp/create-class spec as-component))
(defn fn-to-class [f] (defn fn-to-class [f]
(let [spec (meta f) (let [spec (meta f)
withrender (assoc spec :component-function f) withrender (assoc spec :component-function f)