2014-09-18 19 views
6

爲什麼在子組件計數器更新很好,當我評論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}}) 
+1

這個問題已經被在clojurescript谷歌組上回答:https://groups.google.com/forum/#!topic/clojurescript/5rCTfnulNXI – 2014-09-19 07:54:05

+1

你可以自我回答:) – zarkone 2015-07-29 06:06:49

回答

0

回答上https://groups.google.com/forum/#!topic/clojurescript/5rCTfnulNXI

隨着行41註釋掉以下似乎發生:

  1. 父組件的狀態改變

  2. om/react「走出去」,在父母的組件樹呈現,看看有什麼需要更新

  3. 對於子組件,在第45行用om/build查找子組件已經存在,所以沒有創建新組件或未安裝新組件。

  4. 然而,「運行」 /電話線45 om/build{:init-state ...}

  5. 創建一個新的訂閱到event-pub通過:subscriber/:create-subscriber不會有創建一個新的組件,這將產生一個去環,從消費這個新的用戶渠道(從有22行對om/will-mount沒有呼籲一個新的組件)

  6. 現在event-pub有兩個用戶,但只有一個go-loop從一個通道消耗。在:event-ch這家酒吧將阻止頁面

好像你不應該有在{:init-state ...}傳遞給om/build副作用的[1] [2]

  • 怪誕。而是通過:init-stateevent-pub傳遞給子組件,並創建子陳以及go-loop以從中消耗。

    [1] http://clojure.github.io/core.async/#clojure.core.async/pub 「每個項目並行且同步地分配給所有子項目,即每個子項目必須在分配下一個項目之前接受。使用 緩衝/窗口,以防止慢潛艇持有了酒吧。」

    [2]玩弄緩衝滻在線57看到這種行爲改變的一對夫婦的點擊