2016-10-14 21 views
5

Birkaç seçeneğim var ama ikisi de biraz sarsıntılı görünüyor ve daha iyi bir alternatif olması gerektiğini düşünüyorum. Sadece formları oluşturabilmek, hatta dinamik olarak onları oluşturmak (örneğin, app'ımın içinden bir forma satır eklemek) ve farklı girişlerin değerlerine reaktif/yeniden çerçeve/tepki-uygun erişime sahip olmak istiyorum. ... ikisi de her :on-change sonra fonksiyonlarını çalıştırmak beri bunlardan birini olsa iyi alternatiftir iseClojure Yeniden Çerçevesinde giriş öğelerini nasıl ele alırım?

emin değil

Seçenek 1. - küresel atom

[:input {:value  @new-job-form 
     :on-change #(dispatch [:new-job-form (-> % .-target .-value)])}] 

(reg-event-db 
:new-job-form 
(fn [db [_ v]] 
    (assoc db :new-job-form v))) 

içine güncelleme :on-changeSeçenek # 2 - yalnızca genel atom için gönderilen bazı yerel durumu güncelle :on-blur

(defn text-input 
    "adapted from: 
    https://yogthos.net/posts/2016-09-25-ReagentComponents.html 

    The big idea is this holds local state, and pushes it to the global 
    state only when necessary" 
    [{:keys [sub-path disp]}] 
    (r/with-let [value (r/atom nil) 
       focused? (r/atom false)] 
    [:div 
    [:input 
     {:type  :text 
     :on-focus #(do (reset! value @(subscribe sub-path)) 
         (reset! focused? true)) 
     :on-blur #(do (dispatch (conj disp @value)) 
         (reset! focused? false)) 
     :value  (if @focused? @value @(subscribe sub-path)) 
     :on-change #(reset! value (-> % .-target .-value))}]])) 

İkinci seçenek biraz daha az laggy, ama sadece ham metin girişi daha laggy ...

DÜZENLEME:

Seçenek 3. - eksiksizliği, biraz daha farklı bir tat yeniden uyarlanan -Frame en TODOMVC

(defn text-input 
    "adapted from re-frame's TODOMVC: 
     https://github.com/Day8/re-frame/blob/master/examples/todomvc/src/todomvc/views.cljs 

    note: this is one-way bound to the global atom, it doesn't subscribe to it" 
    [{:keys [on-save on-stop props]}] 
    (let [inner (r/atom "")] 
    (fn [] [:input (merge props 
          {:type  "text" 
          :value  @inner 
          :on-blur  (on-save @inner) 
          :on-change #(reset! inner (-> % .-target .-value)) 
          :on-key-down #(case (.-which %) 
              13 (on-save @inner) ; enter 
              27 (on-stop) ; esc 
              nil)})]))) 

[text-input {:on-save #(dispatch [:new-job-form {:path [:a] 
                 :v %}]) 
        :on-stop #(js/console.log "stopp") 
        :props {:placeholder "url"}}] 
+0

Ne demek laggy? Performansta görünür bir düşüş yaşar mısınız? Tanımladığınız iki yöntemden birini kullanarak çok fazla şey başardım ve hiçbir zaman performans sorunlarım olmadı. –

+0

@KubaBirecki evet, metin kutusu yazım ile devam etmek için mücadele olarak performans görünür bir düşüş var. Hızlı bir bilgisayarım var, neden yavaş olmasının başka açık bir nedeni yok. –

+0

Gereksinimlerinizin tam olarak ne olduğunu açıklığa kavuştum, ancak todomos re-frame'e ve todos'u nasıl eklediğine bakarak başlatabilirim ve başladığınıza bakın: https://github.com/Day8/re -Frame/ağaç/ana/örnekler/todomvc –

cevap

0

Yeniden çerçeve ve bir alt katında reagent + React, değiştirmek bileşenlere yeniden oluşturmayı sınırlamak için deneyin. Sizin durumunuzda, değişmiş olan tek şey olan metin alanına ek olarak başka bir bileşen (veya tüm UI) yeniden oluşturuluyorsa, gecikme ortaya çıkabilir. slow-component işlemek için en az 2000 ms sürdüğünden

(defn busy-wait [ms] 
    (let [start (.getTime (js/Date.))] 
    (while (< (.getTime (js/Date.)) (+ start ms))))) 

(defn slow-component [] 
    (busy-wait 2000) 
    (.log js/console "Ouch!") 
    [:h2 "I was busy"]) 

(defn main-panel [] 
    (let [new-job-form (re-frame/subscribe [:new-job-form]) 
    (fn [] 
     [:div.container-fluid 
     (slow-component) 
     [:input  {:value @new-job-form 
     :on-change #(dispatch [:new-job-form (-> % .-target .-value)])}] 
;; etc 

Bu, slow-component her zaman metin girilir yeniden render yol açar ve gerçekten gecikme oluyor: senin "Seçeneği one" konulu

bir örnek bina. Yukarıdaki durumda

, basit bir çözüm, yani bir vektör içine çağrı değişen yeniden çerçeve bir fonksiyon olarak slow-component sağlamaktır:

[:div.container-fluid 
    [slow-component] 

Bu, yeniden çerçeve görmek sağlar Verileri değişmediğinden slow-component'un yeniden oluşturulmasına gerek yoktur.

[:div.container-fluid 
    (slow-component) 

İyi bir uygulama abonelikler ile birleştirme sırasında Form-2 components kullanmak da şudur: Biz orijinal örnekteki fonksiyonu kendimizi çağırdığınızda Biz bu mantığı atlayın.

İlgili konular