Fix bug with unmounted items crashing it

Close core.async channels on unmount, check for unmounted before calling
	get-node in listeners
This commit is contained in:
Nicholas Kariniemi 2014-08-07 23:40:48 +03:00
parent d05df00797
commit c90c5e41d2
3 changed files with 55 additions and 20 deletions

View file

@ -63,7 +63,8 @@
(init-state [_] (init-state [_]
(let [publisher (chan)] (let [publisher (chan)]
{:edit-state :waiting {:edit-state :waiting
:grub grub})) :grub grub
:unmounted false}))
om/IRenderState om/IRenderState
(render-state [_ {:keys [edit-state] :as state}] (render-state [_ {:keys [edit-state] :as state}]
@ -87,17 +88,27 @@
:on-change #(om/set-state! owner :grub (.. % -target -value)) :on-change #(om/set-state! owner :grub (.. % -target -value))
:on-key-up #(when (dom/enter-pressed? %) (transition-state owner :enter))}]])) :on-key-up #(when (dom/enter-pressed? %) (transition-state owner :enter))}]]))
om/IWillMount om/IDidMount
(will-mount [_] (did-mount [_]
(let [<events (om/get-shared owner :<events) (let [<events (om/get-shared owner :<events)
subscriber (chan)] subscriber (chan)]
(om/set-state! owner :subscriber subscriber)
(a/sub <events :body-mousedown subscriber) (a/sub <events :body-mousedown subscriber)
(a/sub <events :body-scroll subscriber) (a/sub <events :body-scroll subscriber)
(go-loop [] (let [event (<! subscriber)] (go-loop [] (let [event (<! subscriber)]
(when (and (= (:type event) :body-mousedown) (when-not (or (om/get-state owner :unmounted)
(not (dom/click-on-self? (:event event) (nil? event))
(om/get-node owner)))) (when (and (= (:type event) :body-mousedown)
(transition-state owner :body-mousedown)) (not (dom/click-on-self? (:event event)
(when (= (:type event) :body-scroll) (om/get-node owner))))
(transition-state owner :scroll)) (transition-state owner :body-mousedown))
(recur))))))) (when (= (:type event) :body-scroll)
(transition-state owner :scroll)))))))
om/IWillUnmount
(will-unmount [_]
(let [<events (om/get-shared owner :<events)
subscriber (om/get-state owner :subscriber)]
(om/set-state! owner :unmounted true)
(a/unsub <events :body-mousedown subscriber)
(a/unsub <events :body-scroll subscriber)
(a/close! (om/get-state owner :subscriber))))))

View file

@ -59,7 +59,8 @@
(let [publisher (chan)] (let [publisher (chan)]
{:edit-state :waiting {:edit-state :waiting
:name (:name props) :name (:name props)
:grubs (:grubs props)})) :grubs (:grubs props)
:unmounted false}))
om/IWillReceiveProps om/IWillReceiveProps
(will-receive-props [this next-props] (will-receive-props [this next-props]
@ -101,12 +102,23 @@
:on-click #(transition-state owner :save)} :on-click #(transition-state owner :save)}
"Save"]]]))) "Save"]]])))
om/IWillMount om/IDidMount
(will-mount [_] (did-mount [_]
(let [<events (om/get-shared owner :<events) (let [<events (om/get-shared owner :<events)
subscriber (chan)] subscriber (chan)]
(om/set-state! owner :subscriber subscriber)
(a/sub <events :body-mousedown subscriber) (a/sub <events :body-mousedown subscriber)
(go-loop [] (let [event (<! subscriber)] (go-loop [] (let [event (<! subscriber)]
(when-not (dom/click-on-self? (:event event) (om/get-node owner)) (when-not (or (nil? event)
(transition-state owner :body-mousedown)) (om/get-state owner :unmounted))
(recur))))))) (when-not (dom/click-on-self? (:event event) (om/get-node owner))
(transition-state owner :body-mousedown))
(recur))))))
om/IWillUnmount
(will-unmount [_]
(let [<events (om/get-shared owner :<events)
subscriber (om/get-state owner :subscriber)]
(om/set-state! owner :unmounted true)
(a/unsub <events :body-mousedown subscriber)
(a/close! (om/get-state owner :subscriber))))))

View file

@ -39,7 +39,8 @@
(let [publisher (chan)] (let [publisher (chan)]
{:edit-state :waiting {:edit-state :waiting
:new-recipe-name "" :new-recipe-name ""
:new-recipe-grubs ""})) :new-recipe-grubs ""
:unmounted false}))
om/IRenderState om/IRenderState
(render-state [this {:keys [edit-state new-recipe-name new-recipe-grubs]}] (render-state [this {:keys [edit-state new-recipe-name new-recipe-grubs]}]
@ -73,10 +74,21 @@
(let [<events (om/get-shared owner :<events) (let [<events (om/get-shared owner :<events)
subscriber (chan)] subscriber (chan)]
(a/sub <events :body-mousedown subscriber) (a/sub <events :body-mousedown subscriber)
(om/set-state! owner :subscriber subscriber)
(go-loop [] (let [event (<! subscriber)] (go-loop [] (let [event (<! subscriber)]
(when-not (dom/click-on-self? (:event event) (om/get-node owner)) (when-not (or (nil? event)
(transition-state owner :body-mousedown)) (om/get-state owner :unmounted))
(recur))))))) (when-not (dom/click-on-self? (:event event) (om/get-node owner))
(transition-state owner :body-mousedown))
(recur))))))
om/IWillUnmount
(will-unmount [_]
(let [<events (om/get-shared owner :<events)
subscriber (om/get-state owner :subscriber)]
(om/set-state! owner :unmounted true)
(a/unsub <events :body-mousedown subscriber)
(a/close! (om/get-state owner :subscriber))))))
(defn view [recipes owner] (defn view [recipes owner]
(reify (reify