Last active
August 29, 2015 14:11
-
-
Save thosmos/2d3dae5ce298f8a952b8 to your computer and use it in GitHub Desktop.
Imagining atomatizing the App
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; 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