2012-07-02 8 views
6

Gibt es eine Clojurescript-Bibliothek, die das DOM wie eine Clojure-Datenstruktur aussehen lässt? Ich fand ein paar Bibliotheken wie Enfocus, die bestimmte Arten von DOM-Manipulation zu tun, aber was ich will ist in der Lage sein, das DOM so zu behandeln:Clojurescript-DOM-Schnittstelle

(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 

und so weiter

+0

ok gerade gefunden Domina - nächste Sache – Hendekagon

Antwort

4

Clojure Datenstrukturen sind alle persistenten , aber in Ihrem Beispiel scheint es so, als ob Sie eine Nebenwirkung haben möchten (dh das DOM an Ort und Stelle drücken, um es zu ändern).

Das ist ein ziemlich prozeduraler/imperativer Ansatz, so dass es sich lohnen kann, das Problem in einem funktionelleren Stil zurückzuwerfen und neu zu formulieren. Meine persönliche Philosophie besteht darin, "Ansichten als Daten" zu behandeln und sie mit den beständigen Datenstrukturen von Clojure bis zur letzten Minute zu modellieren, wenn ich sie rendern muss.

Kennen Sie Hiccup? Die Idee ist, ein HTML oder SVG DOM Ebene Vektoren und Karten darzustellen:

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

, die Sie mit dem Komponieren plain old Clojure Funktionen konstruieren können. In Clojure können Sie dies in HTML (mit der ursprünglichen Hiccup-Bibliothek) rendern, aber es gibt mindestens zwei ClojureScript-Bibliotheken, die direkt in (möglicherweise vorhandene) DOM-Strukturen rendern. Crate ist ein enger Port von Hiccup, und Singult hat einige zusätzliche Semantik wie D3.js-inspirierte Datenbindung (Singult ist tatsächlich in CoffeeScript geschrieben, so ist es aus reinem JavaScript und ist schneller als Crate).

Meine C2-Bibliothek erstellt eine Datenbindungssemantik über Singult, um das DOM mit den zugrunde liegenden Daten synchron zu halten. diese Vorlage Betrachten wir für einen ToDo-Liste:

(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*)]]) 

(entnommen aus C2 TodoMVC implementation). Dinge wie, ob das "check all" Kontrollkästchen aktiviert ist, ist direkt von den zugrunde liegenden Daten abgeleitet (in einem Atom gespeichert). Immer wenn sich diese Daten ändern, wird die Vorlage erneut ausgeführt und das dom wird automatisch aktualisiert.

Die Grundidee besteht darin, Zuordnungen in Vorwärtsrichtung von Ihren Anwendungsdaten zu Hiccup-Datenstrukturen zu erstellen und dann die Bibliothek für die Synchronisierung des DOM zu sorgen (Hinzufügen/Entfernen von untergeordneten Elementen, Attribute, & c.). Wenn Sie sich nicht mit dem Status des DOM befassen müssen (wurde dieser bereits hinzugefügt? Muss ich eine Klasse umschalten?), Dann fällt eine Menge zufällige Komplexität weg.

+0

Danke. Ich habe tatsächlich daran gedacht, vorherige DOM-Elemente zu entfernen und sie mit neu erzeugten zu ersetzen, indem ich DOM-Fragmente als Clojure-style-persistente Strukturen behandelt (aber als "unveränderliche" DOM-Fragmente implementiert). Jetzt, wo ich darüber nachdenke, wäre es wahrscheinlich langsam und verschwenderisch. Ich werde deine Bibliothek ausprobieren ... kann es SVG? – Hendekagon

+0

Hallo, ich habe versucht, das Balkendiagramm Beispiel auf http://keminglabs.com/c2/, und ich bekomme "Uncaught Error: TODO: Karte der Elementstile zurückgeben". Es hat auch eine Weile gedauert, um herauszufinden, welche Dinge benötigt werden: verwenden und: verwenden-Makros, da die meisten Beispiele isolierte Codefragmente sind. Sieht aber interessant aus. Wie verwalten Sie die Zuordnung von Daten zu Dom-Elementen bezüglich der Identität dieser Knoten? Wie kann man vereinheitlichen, welche Daten welchen Knoten im Dom entsprechen und ob neue hinzugefügt werden? – Hendekagon

+0

Ja, es kann mit SVG gut umgehen. Singult wird die gemeinsamen SVG-Elemente automatisch benennen (, , & c.) Für Sie auch (also müssen Sie nicht sagen, zB '[: svg: rect {: x 1}]'. –