2012-07-02 7 views
6

¿Hay una biblioteca Clojurescript que hace que DOM parezca una estructura de datos Clojure? He encontrado un par de librerías como Enfocus que hacen ciertos tipos de manipulación del DOM, pero lo que quiero es ser capaz de tratar el DOM como esto:Interfaz Clojurescript DOM

(get dom id) - returns element called id in dom 
(get dom id create-fn) - return element if exists, otherwise creates it 
(update-in dom [:body this that] update-fn) - set attribute on a DOM element 
(assoc parent-element id child-element) - associate child element with parent 
(conj parent child) - append child element to parent element 

y así sucesivamente

+0

bien acaba de encontrar Domina - lo más cercano – Hendekagon

Respuesta

4

estructuras de datos Clojure son todos persistente , pero en su ejemplo parece que desea un efecto secundario (es decir, golpear el DOM en su lugar para cambiarlo).

Ese es un enfoque bastante imperativo de procedimiento, por lo que puede valer la pena dar un paso atrás y reformular el problema en un estilo más funcional. Mi filosofía personal es tratar "vistas como datos", y modelarlo utilizando las estructuras de datos persistentes de Clojure hasta el último minuto cuando necesito renderizar.

¿Conoces Hiccup? La idea es representar una página HTML o SVG DOM usando vectores sin ilustrar y mapas:

[:div {:with "attribute"} "and" [:span "children"]] 

que se puede construir mediante la composición de funciones Clojure llanura de edad. En Clojure puede procesar esto en HTML (usando la biblioteca Hiccup original), pero hay al menos dos bibliotecas ClojureScript que se procesan directamente en estructuras DOM (potencialmente existentes). Crate es un puerto cercano de Hiccup, y Singult tiene alguna semántica adicional como el enlace de datos inspirado en D3.js (Singult está escrito en CoffeeScript, por lo que se puede usar desde JavaScript y es más rápido que Crate).

Mi biblioteca C2 construye una semántica de enlace de datos sobre Singult para mantener el DOM sincronizado con los datos subyacentes. Considere esta plantilla para una lista TODO:

(bind! "#main" 
     [:section#main {:style {:display (when (zero? (core/todo-count)) "none")}} 
     [:input#toggle-all {:type "checkbox" 
          :properties {:checked (every? :completed? @core/!todos)}}] 
     [:label {:for "toggle-all"} "Mark all as complete"] 
     [:ul#todo-list (unify (case @core/!filter 
           :active (remove :completed? @core/!todos) 
           :completed (filter :completed? @core/!todos) 
           ;;default to showing all events 
           @core/!todos) 
           todo*)]]) 

(tomado de C2 TodoMVC implementation). Las cosas como si la casilla "marcar todo" está marcada o no se deriva directamente de los datos subyacentes (almacenados en un átomo). Siempre que los datos cambien, la plantilla se volverá a ejecutar y el dom se actualizará automáticamente.

La idea básica es crear asignaciones hacia adelante desde los datos de su aplicación a estructuras de datos Hiccup, y luego dejar que la biblioteca se encargue de sincronizar el DOM (agregar/eliminar elementos secundarios, atributos, & c.). Si no tiene que preocuparse por el estado del DOM (¿ya ha sido agregado? ¿Necesito alternar alguna clase?), La complejidad incidental disminuye.

+0

Gracias. En realidad, estaba pensando en eliminar los elementos DOM anteriores e intercambiarlos con los recién generados al tratar los fragmentos DOM como estructuras persistentes estilo Clojure (pero implementadas como fragmentos DOM "inmutables"). Sin embargo, ahora que lo pienso, probablemente sea lento y derrochador. Probaré tu biblioteca ... ¿puede SVG? – Hendekagon

+0

hola, probé el ejemplo del gráfico de barras en http://keminglabs.com/c2/, y me aparece "Error no detectado: TODO: mapa de devolución de estilos de elemento". También llevó un tiempo determinar qué cosas requerir: uso y uso de macros, ya que la mayoría de los ejemplos son fragmentos de código aislados. Parece interesante sin embargo. ¿Cómo maneja el mapeo de datos a elementos dom con la identidad de esos nodos? ¿Cómo sabe unificar qué datos corresponden a qué nodos en el dom y si agregar o no nuevos? – Hendekagon

+0

Sí, puede manejar SVG sin problemas. Singult automáticamente nombrará los elementos comunes de SVG (, , & c.) para usted también (por lo que no tiene que decir, por ejemplo, '[: svg: rect {: x 1}]'. –

Cuestiones relacionadas