无法在渲染阶段之外操纵光标

时间:2014-07-03 08:26:30

标签: clojurescript om

第一次尝试做出反应,我想做一个简单的待办事项列表应用程序。但每次按Enter键触发onSubmit时都会显示Uncaught Error: Cannot manipulate cursor outside of render phase, only om.core/transact!, om.core/update!, and cljs.core/deref operations allowed。虽然我认为这是一个非常好的错误信息,但我不知道该怎么做。

(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})

2 个答案:

答案 0 :(得分:5)

我认为问题出在你在om / transact中访问data的地方!您应该在v上操作的地方:

(:current v)代替(:current data)

或者您可以尝试(:current @data)获取最新的数据值

答案 1 :(得分:1)

实际上有两个问题:

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

一个是@edbond上面所说的:你应该使用(:current v)而不是(:current data)。另一个问题是,您指定的是:todos关键字,而应该只更改data本身,因为:current位于您应用中的:todos之外 - 显示状态。所以正确的表述是:

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