3

私は、clojurescript と試薬を使用して単純な Web アプリに取り組んでいます。テキスト入力コンポーネントを含む単純な「タブ」コンポーネントを作成したいと思います。

アプリには 2 つのタブがあり、ユーザーはタブを選択するオプションがあり、これら 2 つのタブのそれぞれの値を「保持」したいと考えています。

コードは次のとおりです。

(defn atom-input [value]
  [:input {:type "text"
           :value @value
           :on-change #(reset! value (-> % .-target .-value))}])

(defn simple-tab [index]
  (let [pg-index (atom 1)
        a (atom 0)]
    (fn []
    [:div
     [:h4 (str "index: " @index)]
     [atom-input a]])))

(defn main-page []
  (let [index (atom 0)]
    [:div.container
     [:div.row
      [:button {:on-click (fn [] (reset! index 0))} "select tab 1"]
      [:button {:on-click (fn [] (reset! index 1))} "select tab 2"]]
     [:div.row
      [simple-tab index]]]))

(defn ^:export run []
  (reagent/render-component
   (fn [] [main-page])
   (.-body js/document)))

問題は、タブを切り替えると、コンポーネントが入力フィールドの値を共有することです。ここで何が間違っていますか?

手伝ってくれてどうもありがとう!

4

3 に答える 3

2

a (atom 0)問題は、atom-inputコントロールに渡していることです: [atom-input a]。これにより、同じアトム値がタブ間で共有されていました。

値を共有したくない場合はa、 map: に変更し、a (atom {})マップとインデックスを に渡す必要がありますatom-input

(defn atom-input [value index]
  [:input {:type "text"
           :value (or (get @value index) "")
           :on-change #(swap! value assoc index (-> % .-target .-value))}])

(defn simple-tab [index]
  (let [pg-index (atom 1)
        a (atom {})]
    (fn []
      [:div
       [:h4 (str "index: " @index)]
       [atom-input a @index]])))

より良いアプローチ、私見は、カーソルを使用することです。そのため、インデックスとマップ全体を に渡す必要はありませんatom-input。たとえば、次のようになります。

(defn atom-input [value]
  [:input {:type "text"
           :value (or @value "")
           :on-change #(reset! value (-> % .-target .-value))}])

(defn simple-tab [index]
  (let [pg-index (atom 1)
        a (atom {})]
    (fn []
      [:div
       [:h4 (str "index: " @index)]
       [atom-input (reagent/cursor [@index] a)]])))
于 2015-01-06T14:39:51.053 に答える
2

アプリケーション データ (状態) と表示ロジック データ (つまり DOM) を混同しているため、いくつかの問題があると思います。アプリケーションの状態を 1 つのアトムで維持し、コンポーネントの表示に関連するデータを別のアトムで維持するなど、2 つのことを区別しておくと、少しすっきりするかもしれません。

単純なタブ コンポーネントは、タブの状態について何も知る必要はありません。アプリの状態、つまりアトム入力を介して入力/保存された値について知る必要があるだけです。したがって、インデックスを渡すのではなく、使用するアトムを渡します。これには、呼び出しを決定するためのより高度なロジックが必要になります。たとえば、いくつかのタブがある場合、次のようなものがあるかもしれません

(condp = @index
  0 [simple-tab tab0-atom]
  1 [simple-tab tab1-atom]
  ...
  n [simple-tab tabn-atom])

または、単純なタブを変更して、渡された値、つまりインデックス値がアプリ状態へのキーとして使用されるようにすることもできます-カーソルが最も簡単だと思います

(def app-state (r/atom {:tabs {0 nil 1 nil}}})

(defn simple-tab [index]
  (let [val-cur (r/cursor app-state [:tabs index])]
    [atom-input val-cur]))
于 2015-10-07T00:53:37.997 に答える