CrossClj

0.1.8 docs

SourceDocs



RECENT

    io.cronic/atombind

    Clojars

    Mar 25, 2015


    Readme

    Index of all namespaces


    « Project + dependencies

    Enables dom data binding to clojure data structures.

    The README below is fetched from the published project artifact. Some relative links may be broken.

    Atombind

    A ClojureScript library for binding atoms to dom elements.

    This enables us to manipulate atoms and data structures using familiar ClojureScript code, and have them reflected in the DOM immediately.

    Quickstart

    This quickstart guide assumes:

    • You have a Leiningen project set up using ClojureScript
    • You are familiar with ClojureScript compilation
    • Familiar with Clojure(script) data structure manipulation
    • Basic HTML and JavaScript knowledge

    Add the following dependency to your existing Leiningen ClojureScript project:

    [io.cronic/atombind "0.1.8"]
    

    In your CLJS file, expose the map that you’re interested in binding (it must be a cljs map, or something that implements IMap):

    (ns app
        (:require [atombind.core :as atombind]))
    
    (def ^:export todos
         (atom {:list-name "Stuff to do today"
                :todos [(atom {:text "Learn atombind"})
                        (atom {:text "Make my awesome app"})]}))
    
    (defn ^:export start
          []
          (atombind/start))
    

    In your HTML file, you can then bind like so:

    <div bind-scope='app.todos'>
         <div class="list-name">List name: <span bind='list_name'></span></div>
         <ul>
         <li bind-each='todos'><span bind='text'></span></li>
         </ul>
    </div>
    <script src='app.js'></script>
    <script>
    app.start();
    </script>
    

    Things to note here:

    • You need to use the fully qualified name of the data structure you are attempting to bind. In our case, it is ‘app.todos’.
    • Notice the use of list_name rather than list-name - this is because during compilation of cljs, the dash - gets converted to an underscore _ - just something to be aware of.

    Let’s make this a tad bit more interesting by adding a function that allows us to add a new TODO. For now, let’s just make it add a new TODO with the same text every time it is called:

    (ns app)
    
    (defn add-todo
      "Adds a single todo to the given atom."
      [m initial-text]
      (update-in m
                 [:todos]
    	     conj (atom {:text initial-text})))
    
    (def ^:export todos
         {:list-name "Stuff to do today"
          :todos [(atom {:text "Learn atombind"})
                  (atom {:text "Make my awesome app"})]}
          :add-todo #(swap! % add-todo "Hello world!"))
    

    Our newly added function is fairly familiar looking Clojure data manipulation code. The atombind library uses its own form of dirty checking (based on object equality) to determine when the elements associated with that scope need to be re-rendered. Other things to note:

    • Items within collections must themselves be map atoms. They effectively define another scope which is bound to each ‘bind-each’ repeated element.
    • Functions in maps, when invoked via atombind, are invoked with the atom itself as the first parameter.

    Let’s add a button that triggers our new function:

    <div bind-scope="app.todos">
         ...
         <button type="button" bind-func="click|add-todo">Add a new TODO</button>
    </div>
    ...
    

    Wrap-up

    This demonstrates the very basic flow of using atombind. We introduced a data structure and bound values within it to elements on the dom. We then demonstrated that manipulating that atom will be reflected in the dom. Other features that aren’t mentioned in this quickstart guide include:

    • Two-way data binding with input fields
    • Attribute manipulation based on atom constants
    • Hide/show based on atom contents

    Where to go next: