1

我有一个试剂,可以在单击后退和前进按钮时在所有页面上工作。但是,当页面被刷新时,它会引发异常。

我的应用从 Firebase 和sets一个原子中获取数据。然后随着 UI 的渲染。视图从 atom 中获取数据并呈现 UI。

但是当我刷新时,似乎页面是在我的 Atom 被 Firebase 填充之前呈现的,这会导致异常,因为数据尚不可用。

注意:当我只刷新页面(println clicked-job uid)而不渲染标记时,println运行两次,第一次返回nil,第二次返回数据。

/* Atom */
(def current-view (atom {"jobs-list" {}}))

/* Helper Functions */
(defn set-list! [value]
  (swap! app-state assoc-in ["jobs-list"] value))

(defn clicked-job [uid]
  (get-in @app-state ["jobs-list" uid]))

/* View */
(defn job-view [uid]
  (let [job clicked-job uid)]  
    [:div
      [:div (job "name")]  /***THROWS EXCEPTION HERE***/
      [:a.routes {:href "#/"} "home page"])

/* Fetch data from Firebase and put it in Atom */
(let [fb (js/Firebase. "https://firebaseio.com/listings")]
   (.on fb "value" #(set-list! (js->clj (.val %)))))

/* Set app-view to current-view */
(defn app-view []
    [:div (@data/current-view)])

/* Render app-view */
(reagent/render-component [app-view] (.getElementById js/document "app"))

任何有助于正确刷新页面的帮助!

4

2 回答 2

0

我需要一个“网关”来确保如果我的状态还没有准备好我的渲染代码不会运行。

简单的方法是使用 if 语句。如果我的 atom 还没有被 Firebase 设置,什么也不做。如果已设置,则渲染视图。而且由于 Reagent 会在数据更改时自动呈现视图,因此您不必担心任何进一步的接线。

这是一个伪代码示例:

 (if (empty? (data/get-list!))
   (println "True. Atom is empty. Do not start rendering.")
   (render-view)
 )
于 2015-01-10T01:01:44.647 回答
0

您可以做的另一件事是对您的原子使用 defonce 而不是 def。这将防止您在重新加载页面时重新定义您的原子形式。看看figwheel 页面,最后是关于编写可重载代码的有用部分。

于 2015-10-11T08:42:59.487 回答