core.async的pub/sub表现在庵(clojurescript)奇
为什么在子组件计数器更新很好,当我评论core.async的pub/sub表现在庵(clojurescript)奇
(om/update-state! owner :clicked not)
而不是当我在代码中取消注释就出现在父组件的下方? 通过单击按钮更新计数器。
我想要完成的是一个pub/sub机制,所以组件可以以分离的方式交换消息。
您可以通过一个新的项目,将它复制:
lein new mies-om om-channel-test
然后替换下面的代码core.cljs和运行
lein cljsbuild auto
访问index.html页面在一个现代浏览器(例如最新的Chrome)。
的代码:
(ns om-channel-test.core
(:require-macros [cljs.core.async.macros :refer (go)])
(:require [om.core :as om :include-macros true]
[om.dom :as dom :include-macros true]
[cljs.core.async :refer [chan pub <! sub >! timeout put!]]))
(enable-console-print!)
(def app-state (atom {:text "Hello world!"}))
(def event-ch (chan))
(def event-pub
(pub event-ch #(:topic %)))
(defn child [cursor owner]
(reify
om/IInitState
(init-state [_]
{:counter 0})
om/IWillMount
(will-mount [_]
(go (loop [] (<! (om/get-state owner :subscriber))
(println "message received")
(om/update-state! owner :counter inc)
(recur))))
om/IRender
(render [_]
(println "rendering child")
(dom/p nil (om/get-state owner :counter)))
om/IWillUnmount
(will-unmount [_]
(println "unmount"))))
(defn parent [cursor owner]
(om/component
(println "rendering parent")
(dom/div nil
(dom/button #js {:onClick
#(do
#_(om/update-state! owner :clicked not)
(go (>! event-ch {:topic :wizard
:message "hello"})))}
"Click")
(om/build child
cursor
{:init-state
{:subscriber
((om/get-shared owner :create-subscriber) :wizard)}}))))
(om/root
parent
app-state
{:target (. js/document (getElementById "app"))
:shared {:create-subscriber (fn [topic]
(sub event-pub
topic (chan)))
:event-ch event-ch}})
回答上https://groups.google.com/forum/#!topic/clojurescript/5rCTfnulNXI。
随着行41注释掉以下似乎发生:
父组件的状态改变
om/react
“走出去”,在父母的组件树呈现,看看有什么需要更新对于子组件,在第45行用
om/build
查找子组件已经存在,所以没有创建新组件或未安装新组件。然而,“运行” /电话线45
om/build
在{:init-state ...}
创建一个新的订阅到
event-pub
通过:subscriber/:create-subscriber
不会有创建一个新的组件,这将产生一个去环,从消费这个新的用户渠道(从有22行对om/will-mount
没有呼吁一个新的组件)现在
event-pub
有两个用户,但只有一个go-loop
从一个通道消耗。在:event-ch
这家酒吧将阻止页面
好像你不应该有在{:init-state ...}
传递给om/build
副作用的[1] [2]
怪诞。而是通过:init-state
将event-pub
传递给子组件,并创建子陈以及go-loop
以从中消耗。
[1] http://clojure.github.io/core.async/#clojure.core.async/pub “每个项目并行且同步地分配给所有子项目,即每个子项目必须在分配下一个项目之前接受。使用 缓冲/窗口,以防止慢潜艇持有了酒吧。”
[2]玩弄缓冲浐在线57看到这种行为改变的一对夫妇的点击
这个问题已经被在clojurescript谷歌组上回答:https://groups.google.com/forum/#!topic/clojurescript/5rCTfnulNXI – 2014-09-19 07:54:05
你可以自我回答:) – zarkone 2015-07-29 06:06:49