取决于输入 arg 和重新构建中的派生集合

Depend on both input arg and derived collection in re-frame

刚开始使用re-frame,遇到以下困难。我有一个组件 (Form-2),它接受一个参数,基于它创建 reaction,并且 returns 渲染器像这样

(defn some-list [some]
  (let [bars (rf/subscribe [:bars (:id @some)])]
    (fn [some]
      [:ul
       (for [[id b] bars]
         [:li (:name b)])])))

以后我用

来称呼它
(defn some-dashboard [some]
  [:div.some-dashboard
   [some-list some]])

some 是反应。在这里,当我用 [] 调用 some-list 时,它绑定到初始 some 因此 bars 在订阅中始终具有相同的 (:id @some) 并从订阅中获得相同的值。

你能告诉我如何解决吗?提前致谢。

在 clojure slack 社区找到答案。

原来是动态订阅https://github.com/Day8/re-frame/pull/108。公关来了

解决方法是:

  • 将@some中的数据放入app-db中....
  • 因此可以在处理程序本身中访问它

代码

(defn some-list []
  (let [bars (rf/subscribe [:bars])]
    (fn []
      [:ul
       (for [[id b] @bars]    ;;   <---------- remember the @
         [:li (:name b)])])))

(register-sub 
   :bars
   (fn [db _] 
     (let   [some   (reaction (get @db :some)]  
        (reaction  (get-in @db [:bar @some] ))))
;; we should NOT be using the name "some" ... I'm only doing it so it relates back to your question

这就是动态订阅将如何解决这个问题(摘自 here). Original example found here

(defn some-list [some]
  (let [some-id (reaction (:id some))
        bars (rf/subscribe [:bars] [some-id])]
    (fn [some]
      [:ul
       (for [[id b] @bars]
         [:li (:name b)])])))

这就是订阅者的样子(它与上面提交消息中的代码完全相同):

(rf/register-sub
  :bars
  (fn [db _ [some-id]]
    (reaction (get-bars @db some-id))))

我自己注意:在移动到下一个重新框架版本时,不要忘记删除生成的 js 文件。