ClojureScript、Om 和 Om-Bootstrap:单击按钮,使输入可编辑
ClojureScript, Om, and Om-Bootstrap: Click Button, Make Inputs Editable
我正在创建一个页面,使用 om-boostrap 显示然后编辑承租人信息。 (我知道 Clojure,但总体上是 CLJS/Om/React/modern Web 开发的新手。)显示和编辑租户信息之间的 UI 和功能是相似的——两者都可以使用输入字段;编辑只需要字段为 "text" 而不是 "static" 并且需要 "Submit" 和 "Cancel" 按钮。
我面临的问题是我想不出 React/Om 方法来更改这样的组件。视图定义如下:
(defcomponent view [{:keys [id] :as app} owner]
(render
[_]
(let [tenant (get @tenants id)]
(dom/div
(om/build header/header-view app)
(dom/div {:class "h3"} "View Tenant\t"
(utils/button {:on-click (fn []
(om/update-state! owner
#(assoc app :edit? true))
(om/refresh! owner))}
"Edit"))
(om/build tenant-info {:edit? (:edit? app)
:tenant {:id id
:name "Funny name"
:unit-addr "Funny addr"
:rent "Lots of rent"}})))))
我不会在这里粘贴整个 tenant-view
函数,但它使用 om-bootstrap:
为每个租户数据字段构建 Bootstrap 输入
. . .
(let [input-type (if edit? "text" "static")]
(i/input {:ref "name-display"
:type input-type
:label "Tenant Name"
:label-classname "col-xs-2"
:wrapper-classname "col-xs-4"
:value (str name)})
. . .)
我尝试了多种方法。我已经发布了我最近的,使用按钮的 :on-click
功能修改应用程序状态,将 edit?
属性 设置为 true
并提示重新渲染以使输入可编辑。
这不起作用,我在 React 或 Om 文档中找不到指导。
- 以不同方式呈现相同组件的正确方法是什么? (在我的例子中,
view
函数的输入字段。)
- 哪些 React 或 Om 文档是相关的?
更新:当我将 edit?
标志硬编码为 true
时,我可以获得可编辑的输入,因此使输入可编辑不是问题:问题是从 static
到 text
(大概反之亦然)。
我认为问题在于您使用的是 om/update-state!
用于转换组件本地状态,而不是 om/transact!
用于更新传递给组件的道具。所以尝试将您的按钮组件更改为:
(utils/button {:on-click (fn []
(om/transact! owner #(assoc app :edit true)))}
"Edit")
是的,问题与了解应用程序状态和组件状态之间的区别有关。在这种情况下,我们希望影响应用程序状态,我不太了解您的场景,但我认为为此使用组件本地状态会更好。您可以使用 init-state
或 :state
。您可以根据需要使用 om/update-state!
。但是,只需添加到先前的答案中,仅使用 om/update!
来影响您场景中的应用程序状态会更容易。
(utils/button {:on-click #(om/update! app [:edit?] true)}
"Edit")
是另一个选项,您可以让关键字向量尽可能深入到地图中。
这更简洁,但可能会导致 JS 控制台警告,因为我们忽略了 on-click
中的 event
。
我正在创建一个页面,使用 om-boostrap 显示然后编辑承租人信息。 (我知道 Clojure,但总体上是 CLJS/Om/React/modern Web 开发的新手。)显示和编辑租户信息之间的 UI 和功能是相似的——两者都可以使用输入字段;编辑只需要字段为 "text" 而不是 "static" 并且需要 "Submit" 和 "Cancel" 按钮。
我面临的问题是我想不出 React/Om 方法来更改这样的组件。视图定义如下:
(defcomponent view [{:keys [id] :as app} owner]
(render
[_]
(let [tenant (get @tenants id)]
(dom/div
(om/build header/header-view app)
(dom/div {:class "h3"} "View Tenant\t"
(utils/button {:on-click (fn []
(om/update-state! owner
#(assoc app :edit? true))
(om/refresh! owner))}
"Edit"))
(om/build tenant-info {:edit? (:edit? app)
:tenant {:id id
:name "Funny name"
:unit-addr "Funny addr"
:rent "Lots of rent"}})))))
我不会在这里粘贴整个 tenant-view
函数,但它使用 om-bootstrap:
. . .
(let [input-type (if edit? "text" "static")]
(i/input {:ref "name-display"
:type input-type
:label "Tenant Name"
:label-classname "col-xs-2"
:wrapper-classname "col-xs-4"
:value (str name)})
. . .)
我尝试了多种方法。我已经发布了我最近的,使用按钮的 :on-click
功能修改应用程序状态,将 edit?
属性 设置为 true
并提示重新渲染以使输入可编辑。
这不起作用,我在 React 或 Om 文档中找不到指导。
- 以不同方式呈现相同组件的正确方法是什么? (在我的例子中,
view
函数的输入字段。) - 哪些 React 或 Om 文档是相关的?
更新:当我将 edit?
标志硬编码为 true
时,我可以获得可编辑的输入,因此使输入可编辑不是问题:问题是从 static
到 text
(大概反之亦然)。
我认为问题在于您使用的是 om/update-state!
用于转换组件本地状态,而不是 om/transact!
用于更新传递给组件的道具。所以尝试将您的按钮组件更改为:
(utils/button {:on-click (fn []
(om/transact! owner #(assoc app :edit true)))}
"Edit")
是的,问题与了解应用程序状态和组件状态之间的区别有关。在这种情况下,我们希望影响应用程序状态,我不太了解您的场景,但我认为为此使用组件本地状态会更好。您可以使用 init-state
或 :state
。您可以根据需要使用 om/update-state!
。但是,只需添加到先前的答案中,仅使用 om/update!
来影响您场景中的应用程序状态会更容易。
(utils/button {:on-click #(om/update! app [:edit?] true)}
"Edit")
是另一个选项,您可以让关键字向量尽可能深入到地图中。
这更简洁,但可能会导致 JS 控制台警告,因为我们忽略了 on-click
中的 event
。