为什么试剂不会在状态变化时重新呈现我的试剂形式

时间:2015-10-22 09:39:30

标签: clojurescript reagent reagent-forms

我需要创建一个包含select字段的表单,其中的选项取决于当前可用的邮件帐户。我在页面加载后在API请求中检索这些邮件帐户。

以下函数使用select元素创建表单。

(defn create-options [mail-accounts]
  (for [m mail-accounts]
    [:option {:key (keyword (str (:id m)))
              :value (:id m)}
     (:name m)]))

(defn render-mail-account-select [mail-accounts]
  (let [form-state (r/atom {})]
    (fn [mail-accounts]
      (let [form [:form.mailing-form.form-horizontal
                  (into [:select.form-control {:field :list :id :mail-account}]
                        (create-options mail-accounts))]]
        (pprint form)
        [bind-fields form form-state]))))

pprint给出了以下输出:

;; Before the mail-accounts are loaded
[:select.form-control {:field :list, :id :mail-account}]

;; After the state update containing the mail accounts
[:select.form-control
 {:field :list, :id :mail-account}
 [:option {:key :24, :value 24} "First mail account name"]
 [:option {:key :25, :value 25} "Second mail account name"]]

我的问题是我的页面上的选择保持为空,就像选择没有重新渲染一样。

附录

我想我忘了添加一些代码: 我将这个表单包装在一个KIOO组件中,在那里我取消引用我的state原子。

(defsnippet choose-account-panel "html/static-panel.html" [:div.panel]
  []
  {[:h4.panel-title] (content "3. Mail Account wählen")
   [:div.panel-body] (content [render-mail-account-select (:mail-accounts @state)])})

然后该组件调用我的render-mail-account-select函数,并且应该正确地重新呈现表单。

2 个答案:

答案 0 :(得分:4)

当Ratom改变时,您需要取消引用Ratom for Reagent以了解需要再次调用哪些函数。该解除引用需要在render-mail-account-select内的匿名函数或其调用的函数之一中发生。我看不到在这里发生任何解除引用?

有关Reagent渲染的更多详细信息,请参阅文档here

答案 1 :(得分:0)

正如已经指出的那样,你的渲染函数必须引用state atom中的某些东西,以便知道何时需要重新渲染它。但是,如果您还希望显示的表单选择“默认”值,则还需要设置状态原子。

bind-fields调用会将您的表单与state atom相关联。如果state atom中没有任何内容,则表单将为“空白”,即没有选择任何元素。如果这是你想要的,那应该没问题。但是,如果要选择值,则应将该值放在atom中。例如,如果您想要选择第一个项目,则将:24放入状态原子,即

(swap! form-state assoc :mail-account :24)

请注意,我不确定您的选项定义是否正确。文档似乎表明您只需要具有该属性中值(作为关键字)的:key属性。我没有查看源代码来确认这一点,但是没有一个例子也使用:value属性。

如果在渲染函数的开头进行交换,则会引用state atom,并且每次使用新参数调用组件时都应重新渲染。当我说'渲染函数'时,在这种情况下,我的意思是匿名函数,而不是创建状态原子的外部函数。