2013-03-15 10 views
5

Sto sviluppando RIA con clojure e clojurescript. Backend utilizza incidente di percorso per generare un HTML risultante, comeCome posso passare edn al clojurescript da clojure senza fare una richiesta jax (cioè tramite la pagina generata da hiccup)

(html5 
[:head 
    (include-js "/js/my-cljs-generated.js")] 
[:body ... ]) 

Come posso passare EDN (hashmap, vettore, ecc) per ClojureScript all'interno del codice HTML risultante, vale a dire senza fare chiamata AJAX?

vorrei fare singhiozzo fare qualcosa di simile: (. Per esempio in base al nome)

(include-edn 
    "var_name" {:foo :bar}) ; or any other clojure data 

e di essere in grado di accedere al edn passato da cljs in qualche modo.

Attualmente la mia realizzazione è un po 'hacky e memorizza EDN in un js var globale

(hiccup/javascript-tag (str "var edn = \"" 
         (pr-str my-clojure-data) "\";"))   

e sul lato cljs fa smth come

(jayq/document-ready 
    (fn [] 
    (if-let [edn (.-edn js/window)] 
     (do-something-with (cljs.reader/read-string edn)) 
    ) 
    ... 
) 

Forse c'è modo più idiomatico per raggiungere tale obiettivo?

risposta

1

La tua "implementazione" è perfettamente a posto. Avvolgilo in una funzione se ti fa sentire più a tuo agio :)

Non farebbe differenza se tu emettessi ad es. invece compilato ClojureScript; il valore sarebbe ancora globale e mutabile.

1

Si potrebbe prendere in considerazione un approccio push (event-based), piuttosto che tirare: inserire i dati EDN generati come una stringa all'interno di un [: sceneggiatura] tag come argomento di un javascript chiamare una funzione ClojureScript. Quando lo script viene caricato dal browser, invierà l'edn alla funzione del gestore, consentendone il caricamento dall'applicazione.

Questo sarebbe un po 'più idiomatico del tuo attuale approccio in quanto non richiede dati di stato o globali e potrebbe essere facilmente adattato per utilizzare ajax in seguito, se necessario.

+1

Non sarei d'accordo sul fatto che un approccio basato sulla spinta sia più idiomatico. per esempio, core.async tenta di ridurre al minimo l'inversione del controllo che viene normalmente introdotto dai callback. –

2

Il tuo approccio è a posto. Se sei preoccupato per la creazione manuale del codice JavaScript, un'alternativa potrebbe essere quella di inserire il risultato di pr-str come dati in un elemento ben definito. Qualcosa sulla falsariga di:

[:div {:style {:display "hidden"} 
     :id "server-originated-data" 
     :data-var-1 (pr-str var-1) 
     :data-var-2 (pr-str var-2)}] 

Si può quindi ottenere che i dati da ClojureScript con qualcosa di simile:

(defn get-data 
    [tag] 
    (-> (.getElementById js/document "server-originated-data") 
     (.getAttribute (str "data-" tag)) 
     (cljs.reader/read-string))) 

Anche se, ancora una volta, il vostro approccio va bene.

Problemi correlati