输入文本试剂组分值格式

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-changerprice 原子的值设置为一个字符串,但是在这个表达式中 (cl-format nil "~,,' :d" @rprice) @rprice 应该是一个数字
  • 当您将输入的 value 设置为某个格式化值时,下次您键入内容时 on-change 将看到此格式化值而不是您之前的原始输入,因此内容rprice 的将被设置为格式化值,一个字符串

因此,如果您将 rstring 设置为原始数字或格式化字符串,则循环后它将始终是格式化字符串。

不幸的是,在您键入时格式化输入有点复杂,您可能需要一个库。也许 reagent-forms 支持它:https://github.com/reagent-project/reagent-forms,如果不支持,还有其他 React 库支持。