2016-05-04 5 views
0

Рассмотрим следующие гипотетические, упрощенные clojurescript фрагменты:Как перенаправить изменения в компонент реагента с помощью подкадров и обработчиков подкадров?

(def cat (r/atom [{:id 0 :data {:text "ROOT" :test 17} :prev nil :par nil} 
       {:id 1 :data {:text "Objects" :test 27} :prev nil :par 0} 
       {:id 2 :data {:text "Version" :test 37} :prev nil :par 1}])) 

(defn categorymanager [s] 
    [:div 
    [:> Reactable.Table 
    {:data (clj->js 
      s 
      )} 
    ] 
    ] 
) 

(defn content [] 
    (fn [] 
    [:div 
    [:h1 "Test"] 
    (categorymanager (select [ALL :data] (t/tree-visitor @cat))) 
    [re-com/button :label "Do not click!"] 
    ] 
)) 

Функция содержимого подготавливает компонент реагента. Фрагменты кода работают должным образом. (Функция «select» является частью библиотеки Spectre.)

Я хотел бы добавить минимальный код повторного кадра, чтобы при изменении атома кошки, например, с помощью функции из REPL, React .js в браузере. Я знаю теорию о перераспределении подписей и обработчиков, но только в теории, так как я не смог заставить ее работать на таком минимальном примере, как это. Как это делается? Как подтолкнуть изменения к компоненту реагента с помощью подкадров и обработчиков подкадров?

+0

Это не выглядит, как у вас есть какой-либо Перекадрируйте определенный код. Не работает ли это сейчас, когда вы вызываете 'swap!' Или 'reset!' С 'cat' где-то? Также взгляните на https://github.com/Day8/re-frame/wiki/Creating-Reagent-Components – nidu

+0

Я посмотрел на это, и демонстрационные приложения все работают, я хочу заставить его работать с нуля. Атом является реагентом, так что компоненты. Мне нужно подписаться на что-то ... но как? –

+0

Re-frame хранит данные в одном атоме реагента, который он поддерживает. Обычно вы инициализируете db путем отправки на маршрут, который возвращает состояние дебета init db. Вы не работаете с этим db напрямую, а через 'subscribe' и' dispatch'. Посмотрите https://github.com/Day8/re-frame/blob/master/examples/simple/src/simpleexample/core.cljs#L23. – nidu

ответ

1

Сначала вы должны инициализировать приложение-db для повторного кадрирования, отправив какой-то инициализатор. Re-frame работает с его внутренним одиночным приложением-db. Вы можете отправить с dispatch-sync перед установкой верхней части React, таким образом приложение будет отображаться после его инициализации.

Для вашего конкретного примера будет что-то вроде этого (не тестировался на всех):

; Initialize our db here. This one should be called with (re-frame/dispatch-sync [:initialize]) before rendering application. 
(re-frame/register-handler 
    :initialize 
    (fn [_] 
    {:cats [{:id 0 :data {:text "ROOT" :test 17} :prev nil :par nil} 
      {:id 1 :data {:text "Objects" :test 27} :prev nil :par 0} 
      {:id 2 :data {:text "Version" :test 37} :prev nil :par 1}]})) 

; This one returns reaction with relevant cat list. 
(re-frame/register-sub 
    :cats 
    (fn [db] 
    (reaction 
     (get @db :cats)))) 

(defn categorymanager [s] 
    [:div 
    [:> Reactable.Table 
    {:data (clj->js 
      s)}]]) 

(defn content [] 
    ; Here you subscribe to cat list. Once cat list is changed, component is rerendered. 
    (let [cats (re-frame/subscribe [:cats])] 
    (fn [] 
    [:div] 
    [:h1 "Test"] 
    (categorymanager (select [ALL :data] (t/tree-visitor @cats))) 
    [re-com/button :label "Do not click!"])))