2015-05-05 19 views
7

Sto eseguendo un Ajax GET dall'applicazione Reagent per caricare alcune informazioni dal database.Ajax GET con reagente

Non sono del tutto sicuro di quale sia il modo migliore per ottenere il risultato di tale chiamata ajax sulla mia pagina, considerando che se lo metto in un atomo, allora Reagente re-rende automaticamente un componente quando un atomo è dereferenziato, il che significa che ottengo una sequenza infinita di chiamate Ajax.

Per un certo codice,

(def matches (atom nil)) 

(defn render-matches [ms] 
    (reset! matches (into [:ul] (map (fn [m] ^{:key m}[:li m]) 
            (walk/keywordize-keys (t/read (t/reader :json) ms))))) 

Questa funzione fondamentalmente crea un [:ul [:li "Stuff here"] [:li "And here"]]

cui vorrei visualizzati sulla mia pagina, che ora ha il seguente codice.

(defn standings-page [] 
    (GET "/list-matches" 
     {:handler render-matches}) 
    @matches) 
+0

Come viene attivata la richiesta 'GET'? A caricamento della pagina? O solo se hai bisogno di quel componente di reagente? O azione dell'utente? Stai facendo un sacco di cose qui. Metterei solo i dati (non intoppi) nell'atomo e renderemo l'elenco in 'classifiche-page'. Se è necessario richiederlo solo una volta è possibile controllare "ritardo" e fare riferimento al ritardo in "classifica-pagina". Ma ancora una volta, ciò dipende dal tuo caso d'uso (da cui le prime domande) – ClojureMostly

+0

Sì, non chiamare mai il codice effetto collaterale direttamente dal rendering. O farlo da un functin del ciclo di vita (come will-mount o did-mount) o nel init del componente reagente (come mostrato nella risposta di Michiel Borkent). – Dan

risposta

10

Penso che sia meglio salvare solo i dati in un atomo e generare l'HTML come parte della logica del componente.

Inoltre, è preferibile attivare la chiamata AJAX al di fuori della fase di rendering, ad esempio, prima che il componente venga montato, o come risultato di un evento (con un clic su un pulsante, ad esempio).

Ti piace questa:

(def matches (atom nil)) 
(defn component [] 
    (let [get-stuff (fn [] (GET "/..." :handler (fn [response] 
          (reset! matches (:body response))))] 
    (get-stuff) <-- called before component mount 
    (fn [] 
     [:ul 
     (for [m match] 
      ^{:key ...} 
      [:li ...])]))) 

Questo è chiamato modulo-2 in this post.

+1

Grazie Michiel. Il tuo commento è stato molto utile e ho capito la logica un po 'meglio :) Ci vediamo in un Meetup! – Helios

+0

Non è la chiave per form-2 il fatto che si restituisce una funzione? Se è così, perché è necessario usare 'let'? Non potreste fare quanto segue: (corrispondenze (nil atomico) (componente defn [] (GET "/ ...": gestore (fn [risposta] (azzeramento corrispondenze (: risposta del corpo)))) (fn [] [: ul (per [m partita] ^ {: chiave ...} [: li ...])].)) – DandyDev

+0

@DandyDev È possibile ho appena creato il nome per esprimere l'intento, ma puoi fare a meno della funzione. –