输入文本试剂组分值格式
Input text reagent component value formatting
我正在尝试格式化输入 "text" 试剂成分的值,但没有成功。我预计,在更改 ratom 变量的值后,组件的值将在重新渲染时被格式化。
我使用 cl-format 来格式化带有 space 千位分隔符的数字。我在第一次加载时运行良好,但在更改价格值后就不行了。
是否可以在保存新值后格式化此示例的价格值?
(ns shopping.app
(:require [reagent.core :as r]
[cljs.pprint :refer [cl-format]]))
(defonce shoppinglist (r/atom (sorted-map
1 {:id 1 :name "Bread" :price 20},
2 {:id 2 :name "Milk" :price 12})))
(defn update-item! [fn & args]
(apply swap! shoppinglist fn args))
(defn shopping-item [{:keys [id name price]} item]
(let [rreadonly (r/atom true)
rprice (r/atom price)]
(fn [{:keys [id name price]} item]
[:div
[:label id]
[:label (str " | " name)]
[:input { :type "text"
:readOnly @rreadonly
:value (cl-format nil "~,,' :d" @rprice)
:on-change #(reset! rprice (-> % .-target .-value))}]
[:button { :id "button-edit"
:hidden (not @rreadonly)
:on-click #(swap! rreadonly not)}
"Edit"]
[:button { :id "button-delete"
:hidden (not @rreadonly)
:on-click #(update-item! dissoc id)}
"Delete"]
[:button { :id "button-save"
:hidden @rreadonly
:on-click #(do
(update-item! assoc id (assoc {} :id id :name name :price (js/parseInt @rprice)))
(swap! rreadonly not))}
"Save"]
[:button { :id "button-reset"
:hidden @rreadonly
:on-click #(do (reset! rprice price)
(update-item! assoc id (assoc {} :id id :name name :price (js/parseInt @rprice)))
(swap! rreadonly not))}
"Reset"]])))
(defn shopping-list []
[:div.container
(doall (for [item (vals @shoppinglist)]
^{:key (:id item)} [:div
[shopping-item item]]))])
(defn init
"Initialize components."
[]
(let [container (.getElementById js/document "container")]
(r/render-component
[shopping-list]
container)))
这不起作用,因为您正在创建一个循环:
on-change
将 rprice
原子的值设置为一个字符串,但是在这个表达式中 (cl-format nil "~,,' :d" @rprice)
@rprice
应该是一个数字
- 当您将输入的
value
设置为某个格式化值时,下次您键入内容时 on-change
将看到此格式化值而不是您之前的原始输入,因此内容rprice
的将被设置为格式化值,一个字符串
因此,如果您将 rstring
设置为原始数字或格式化字符串,则循环后它将始终是格式化字符串。
不幸的是,在您键入时格式化输入有点复杂,您可能需要一个库。也许 reagent-forms 支持它:https://github.com/reagent-project/reagent-forms,如果不支持,还有其他 React 库支持。
我正在尝试格式化输入 "text" 试剂成分的值,但没有成功。我预计,在更改 ratom 变量的值后,组件的值将在重新渲染时被格式化。 我使用 cl-format 来格式化带有 space 千位分隔符的数字。我在第一次加载时运行良好,但在更改价格值后就不行了。
是否可以在保存新值后格式化此示例的价格值?
(ns shopping.app
(:require [reagent.core :as r]
[cljs.pprint :refer [cl-format]]))
(defonce shoppinglist (r/atom (sorted-map
1 {:id 1 :name "Bread" :price 20},
2 {:id 2 :name "Milk" :price 12})))
(defn update-item! [fn & args]
(apply swap! shoppinglist fn args))
(defn shopping-item [{:keys [id name price]} item]
(let [rreadonly (r/atom true)
rprice (r/atom price)]
(fn [{:keys [id name price]} item]
[:div
[:label id]
[:label (str " | " name)]
[:input { :type "text"
:readOnly @rreadonly
:value (cl-format nil "~,,' :d" @rprice)
:on-change #(reset! rprice (-> % .-target .-value))}]
[:button { :id "button-edit"
:hidden (not @rreadonly)
:on-click #(swap! rreadonly not)}
"Edit"]
[:button { :id "button-delete"
:hidden (not @rreadonly)
:on-click #(update-item! dissoc id)}
"Delete"]
[:button { :id "button-save"
:hidden @rreadonly
:on-click #(do
(update-item! assoc id (assoc {} :id id :name name :price (js/parseInt @rprice)))
(swap! rreadonly not))}
"Save"]
[:button { :id "button-reset"
:hidden @rreadonly
:on-click #(do (reset! rprice price)
(update-item! assoc id (assoc {} :id id :name name :price (js/parseInt @rprice)))
(swap! rreadonly not))}
"Reset"]])))
(defn shopping-list []
[:div.container
(doall (for [item (vals @shoppinglist)]
^{:key (:id item)} [:div
[shopping-item item]]))])
(defn init
"Initialize components."
[]
(let [container (.getElementById js/document "container")]
(r/render-component
[shopping-list]
container)))
这不起作用,因为您正在创建一个循环:
on-change
将rprice
原子的值设置为一个字符串,但是在这个表达式中(cl-format nil "~,,' :d" @rprice)
@rprice
应该是一个数字- 当您将输入的
value
设置为某个格式化值时,下次您键入内容时on-change
将看到此格式化值而不是您之前的原始输入,因此内容rprice
的将被设置为格式化值,一个字符串
因此,如果您将 rstring
设置为原始数字或格式化字符串,则循环后它将始终是格式化字符串。
不幸的是,在您键入时格式化输入有点复杂,您可能需要一个库。也许 reagent-forms 支持它:https://github.com/reagent-project/reagent-forms,如果不支持,还有其他 React 库支持。