2014-07-03 16 views
5

Provare a reagire per la prima volta e voglio creare una semplice app per la lista di cose da fare. Ma ogni volta che preme invio per attivare onSubmit dice Uncaught Error: Cannot manipulate cursor outside of render phase, only om.core/transact!, om.core/update!, and cljs.core/deref operations allowed. Mentre penso che questo sia un messaggio di errore molto buono, non so cosa fare.Impossibile manipolare il cursore all'esterno della fase di rendering

(ns app.core 
    (:require [om.core :as om :include-macros true] 
      [sablono.core :as html :refer-macros [html]])) 

(def app-state (atom 
       {:todos [{:todo "first"} 
         {:todo "second"}] 
       :current ""})) 

(defn to-do 
    [data] 
    (om/component 
    (html [:li (:todo data)]))) 

(defn to-dos 
    [data] 
    (om/component 
    (html [:div 
      [:form {:on-submit (fn [e] 
           (.preventDefault e) 
           (om/transact! data :todos (fn [v] 
                  (js/console.log (:current data)) 
                  (conj v (:current data)))))} 
      [:input {:type "text" 
        :placeholder "Enter some text." 
        :on-change (fn [e] (om/update! data :current (.. e -target -value)))}]] 
      [:ul 
      (om/build-all to-do (:todos data))]]))) 

(om/root to-dos app-state {:target js/document.body}) 

risposta

5

Credo che il problema è dove si accede all'interno data om/transact! dove si dovrebbe operare su v:

(:current v) invece di (:current data)

o si può provare (:current @data) per ultimo valore dei dati

+1

Questo è assolutamente corretto – Dan

+1

Uso '(corrente v)' è molto preferibile accedere al '@ data' cursore nuovamente. C'è un secondo problema qui, però, con l'argomento ': todos' su' om/transcat! '. Vedi la mia risposta qui sotto. – prabhasp

1

In realtà ci sono due problemi con:

(om/transact! data :todos (fn [v] 
    (js/console.log (:current data)) 
    (conj v (:current data))))) 

Uno è cosa ha detto @edbond sopra: dovresti usare (:current v) anziché (:current data). L'altro problema, tuttavia, è che si specifica la parola chiave :todos e, invece, è sufficiente cambiare lo stesso data, dal momento che lo :current non è compreso tra :todos nello stato dell'app visualizzato. Quindi la formulazione corretta sarebbe:

(om/transact! data (fn [v] 
    (js/console.log (:current v)) 
    (conj v (:current v)))))