How are Om objects render objects?

I am struggling with understanding how om apps are applied to render list items as shown in the example below, taken from the Om tutorial page.

(om/root
  (fn [data owner]
    (om/component 
      (apply dom/ul nil
        (map (fn [text] (dom/li nil text)) (:list data)))))
  app-state
  {:target (. js/document (getElementById "app0"))})

      

My understanding of the application is that it takes a function and a list of items and applies that function to the list. But in this example, understanding is translated into using dom/ul

to nil

.

What I don't understand is:

  • Why am I applying dom/ul

    to a list box, I don't want to create items ul

    , I want to create items li

    ?
  • How do I apply a handle to all the parameters sent in this example?
+3


source to share


2 answers


dom/ul

is a function that creates a React component that will render the corresponding DOM element. The first argument dom/ul

specifies the attributes that the DOM elements should have. For example, if you wanted to dom/ul

have a "main" class attribute, you would do the following:

  (apply dom/ul #js {:className "main"}
    (map (fn [text] (dom/li nil text)) (:list data)))

      

Passing nil as the first argument dom/ul

just doesn't set the DOM attributes.

Clojure apply

calls dom/ul

by adding all the arguments (after the argument dom/ul

) to the final list (produced by the map) and passing the result as arguments dom/ul

.

As an example, suppose the data had the following meaning:



["Apple" "Bird"] 

      

then dom/ul

in your example it will end up being called like:

(dom/ul nil
    (dom/li nil "Apple")
    (dom/li nil "Bird"))

      

which will render the following HTML:

<ul>
  <li>Apple</li>
  <li>Bird</li>
</ul>

      

+2


source


When I first started studying Om, it took me a while to understand. The main thing to remember is that each function om.dom

takes a JS attribute map as its first parameter, followed by any number of arguments om.dom

. What you expected, as I did, was that the functions om.dom

will take attributes and a vector of dom elements. As soon as it clicked, a lot of Ohm design got me more understanding.

Clojure enforces "expands" the collection and passes the elements of the collection as arguments to the function to use. So, the intermediate steps in our calculations are:

(apply dom/ul nil
    (map (fn [text] (dom/li nil text)) (:list data)))

      

then

(apply dom/ul nil
    '((dom/li nil "Hi") (dom/li nil "there")))

      



then

(dom/ul nil
    (dom/li nil "Hi") (dom/li nil "there"))

      

Without applying, we will not pass the correct arguments to dom/ul

. You will also see that apply is used with om / build-all, which returns a collection of type map

.

Another example to expand on this, if we want to put two dom/ul

inside dom/p

, it will look like this when expanded:

(dom/p nil
    (dom/ul nil (dom/li nil "Hi") (dom/li nil "there"))
    (dom/ul nil (dom/li nil "Next") (dom/li nil "list")))

      

+2


source







All Articles