Skip to content

Instantly share code, notes, and snippets.

@thosmos
Last active August 29, 2015 14:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thosmos/2d3dae5ce298f8a952b8 to your computer and use it in GitHub Desktop.
Save thosmos/2d3dae5ce298f8a952b8 to your computer and use it in GitHub Desktop.
Imagining atomatizing the App
;; see blog post here: http://code.thosmos.com/om/clojurescript/2014/12/15/imagining-atomatizing-the-app.html
{ :ns "hmmm.core"
:require ["om.core :as om :include-macros true"
"om.dom :as dom :include-macros true"]
:app {
:root [:app-state :app-def {:elementId "content"}]
:app-state {
:comments [
{ :author "Pete Hunt", :text "This is a comment."}
{ :author "Jordan Walke", :text "This is *another* coment"}]}
; do functions need to be stored outside of the atom? Is there a better way to store them within the atom?
:app-fns [
{ :changeAuthor '(fn [state new-author]
(om/update! state (fn [comments]
(mapv #(assoc % :author new-author) comments))))}
{ :multAB '(fn [a b] (* a b))}]
:app-def {
;; version shall be updated on every app-def change
:version "0.1.0"
:content [
{ :kind :commentBox}]
:components [
{ :name :comment
:class "comment"
;:kind :div ; is the default
:content [
{ :kind :h2
:state :author}
{ :kind :span
:state :text}]}
{ :name :commentList
:content [
{ :class "commentList"
:content {:kind [:comment], :build :all}}
{ :kind :button
:onClick [:changeAuthor :state "Frederik"]
:content "Change authors"}]}
{ :name :commentBox
:class "commentBox"
:content [
{ :name :title, :kind :h1, :content "It's all data. The app builder can time travel."}
{ :kind :commentList :state :comments}]}]}}}
;; from https://gist.github.com/fredyr/8460923:
;; Updated tutorial code for Om 0.1.6, 2014-01-16
;; http://www.lexicallyscoped.com/2013/12/25/slice-of-reactjs-and-cljs.html
;; See comments below for details on the changes.
(def app-state
(atom {:comments [{:author "Pete Hunt" :text "This is a comment."}
{:author "Jordan Walke" :text "This is *another* coment"}]}))
(defn comment [{:keys [author text]} owner]
(om/component
(dom/div #js {:className "comment"}
(dom/h2 nil author)
(dom/span nil text))))
(defn change-author [cs new-author]
;; The cursors internal path is used, no explicit path needed
(om/update! cs (fn [comments]
(mapv #(assoc % :author new-author) comments))))
(defn comment-list [cs owner]
(om/component
(dom/div nil
(dom/div #js {:className "commentList"}
;; Helper function build-all builds a vector of components
(om/build-all comment cs))
(dom/button #js {:onClick #(change-author cs "Fredrik")}
"Change authors"))))
(defn comment-box [state owner]
(om/component
(dom/div #js {:className "commentBox"}
(dom/h1 nil "Comment")
;; Cursors support lookups to yield new cursors, so
;; they can be used directly to pass sub-state,
;; maintaining paths internally
(om/build comment-list (:comments state)))))
(om/root
app-state
comment-box
(.getElementById js/document "content"))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment