2017-01-16 6 views
2

あなたは、試薬でcljsで書かれたチャットプログラムの入力であるテキストフィールドがあるとします。チャット入力フィールドはどのように試薬に定義されていますか?

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

メッセージの送信を実装する簡単な方法は、送信ボタンを追加することです。しかし、チャットに不可欠な1つのやりとりがあります。チャットには不可能です。EnterまたはShift-Enterでメッセージが送信されます。しかし、私はそれを実装する方法を理解することはできません。

私の最初の試みは、:on-key-pressイベントハンドラを追加してメッセージを送信し、状態を ""にリセットすることでした。この解決法は、How to detect enter key press in reagentに触発されました。

(defn chat-input [] 
    (let [written-text (atom "")] 
    (fn [] 
     [:textarea 
     {:value  @written-text 
     :on-change #(reset! written-text (-> % .-target .-value)) 
     :on-key-press (fn [e] 
         (let [enter 13] 
          (println "Key press" (.-charCode e)) 
          (if (= (.-charCode e) enter) 
          (reset! written-text "") 
          (println "Not enter."))))}]))) 

:on-key-press(reset! written-text "")への呼び出しは、それが:on-changeイベントハンドラによって上書きだからでしょう、何の効果もありませんということで問題。

この機能を実装する方法はありますか?もしそうなら、共有してください!

答えて

1

正しいトラックにあったが、jsイベントモデルを忘れていた:入力がキー入力を変更するテキストエリアなので、onChangeonKeyPressの両方がトリガされる。したがって、jsではonKeyPressが最初にトリガされ、キーが何か変更された場合はonChangeがトリガされます。何が必要preventDefaultkeyPressのこのデフォルトの動作を無効にすることです:問題を修正する必要があります

(defn chat-input [] 
    (let [written-text (atom "")] 
    (fn [] 
     [:textarea 
     {:value  @written-text 
     :on-change #(reset! written-text (.. % -target -value)) 
     :on-key-press (fn [e] 
         (when (= (.-charCode e) 13) 
          (.preventDefault e) 
          (reset! written-text "")))}]))) 

0

ここでは、mccraigmccraigがclojuriansの余裕をもっていることを親切にして分かち合いました。チャット入力がどのようにスラックで動作するかをエミュレートする入力の内容が大きくなるにつれて、テキストエリアの高さが拡大されます。

しかし、この質問の重要な部分は、:on-key-pressには(.preventDefault e)が含まれているということです。

(defn update-rows 
    [row-count-atom max-rows dom-node value] 
    (let [field-height (.-clientHeight dom-node) 
     content-height (.-scrollHeight dom-node)] 
    (cond 
     (and (not-empty value) 
      (> content-height field-height) 
      (< @row-count-atom max-rows)) 
     (swap! row-count-atom inc) 

     (empty? value) 
     (reset! row-count-atom 1)))) 

(defn expanding-textarea 
    "a textarea which expands up to max-rows as it's content expands" 
    [{:keys [max-rows] :as opts}] 
    (let [dom-node  (atom nil) 
     row-count  (atom 1) 
     written-text (atom "") 
     enter-keycode 13] 
    (reagent/create-class 
    {:display-name "expanding-textarea" 

     :component-did-mount 
     (fn [ref] 
     (reset! dom-node (reagent/dom-node ref)) 
     (update-rows row-count max-rows @dom-node @written-text)) 

     :component-did-update 
     (fn [] 
     (update-rows row-count max-rows @dom-node @written-text)) 

     :reagent-render 
     (fn [{:keys [on-change-fn] :as opts}] 
     (let [opts (dissoc opts :max-rows)] 
      [:textarea 
      (merge opts 
        {:rows  @row-count 
        :value  @written-text 
        :on-change (fn [e] 
            (reset! written-text (-> e .-target .-value))) 
        :on-key-down (fn [e] 
            (let [key-code (.-keyCode e)] 
            (when (and (= enter-keycode key-code) 
               (not (.-shiftKey e)) 
               (not (.-altKey e)) 
               (not (.-ctrlKey e)) 
               (not (.-metaKey e))) 
             (do 
             (.preventDefault e) 
             (send-chat! @written-text) 
             (reset! written-text "")))))})]))}))) 
関連する問題