4

Om コンポーネントのクリック ハンドラー関数を作成したいと考えています。私が見つけたドキュメントとスタックオーバーフローの例では、常にこのような無名関数を宣言しています

(defn main-view [_ owner]
  (reify
  om/IRender
   (render [_]
    (let [xs (items)]
      (dom/div nil
        (om/build sub-view {:title "View A"})
        (om/build sub-view {:title "View B"})
        (dom/button
          #js {:onClick
               (fn [e] (om/transact! xs #(assoc % 1 {:text "zebra"})))}
          "Switch To Zebra!"))))))

通常の React で一般的に行われているように、コンポーネント内の jsx/template 領域の外でクリック関数を宣言する方がクリーンだと思います。コンポーネント内のOmでこれを行う方法はありますか? これを試しましたが、 onClick が定義されていないため機能しません:

(defn my-component []
  (reify
    om/IRender
    (render [this]
       ; Using Sablono syntax
       (html [:h1 "Here is a heading" {:on-click 'onClick} ]))
    onClick
    (onClick [this]
      ; this part never gets executed when you click
      (.log js/console "click"))))

可能であれば、コンポーネントの外部で別の関数を定義することは避けたいです。

4

2 に答える 2

6

あなたの質問は賢明であり、データの範囲の処理に関するものです。

可能ですが、ほとんどの場合、このアプローチの問題は、外部コード ブロックからのローカル スコープ データが必要になります (この場合、それは Om コンポーネントです)。

コードで説明します。ハンドラー関数を移動したいとしましょう:

(anything
 (let [a 1 b 2]
   (on-event (fn my-handler [evt] (log (+ a b (.someAttr evt)))))))

これはずっと長くなります。

(defn local-data->handler [a b]
  (fn [evt] (log (+ a b (.someAttr evt)))))

(anything
 (let [a 1 b 2]
   (on-event (local-data->handler a b))))

コンポーネント定義内を移動したいだけの場合:

(anything
 (let [a 1
       b 2
       my-handler (fn [evt] (log (+ a b (.someAttr evt))))]
   (on-event my-handler)))

注意: イベント ハンドラーの動作を維持するには、(defn または let で作成された) 非匿名関数が匿名形式、特に引数リストと同じであることを確認してください。

onClick は、Om プロトコルのように使用するため未定義です。正しい使用法については、Om ライフサイクル プロトコルを参照してください。

https://github.com/swannodette/om/wiki/Documentation

于 2015-01-13T04:48:41.400 に答える
3

要件に従って、関数定義をコンポーネントから移動する必要があります。

その後、関数の名前をイベント リスナーに渡すことができるはずです。

(defn foo [] (println "foo"))

(defn my-component [text owner]
  (reify
    om/IRender
    (render [_]
        (dom/button
          #js { :onClick foo }
          "Click Here"))))
于 2015-01-13T02:58:13.473 に答える