SPA's are essentially Data Driven Applications
# Single Page Applications
How to develop SPA with confidence using cljs? like the types of gmail
and netflix
and google-drive
which gives us desktop like experience in the comfort of web-browser!
# Reframe (opens new window)
- Reactivity via subscription from data/information modal
- Unidirectional data flow
- Pristinely pure functions
- Interceptors aka Middleware
- SideEffects and Coeffects
- Conveyor belts, UI intention as Event queues
- Statechart-friendliness (FSM) (opens new window)
- Immaculate hammock conception
A User Interface is just derived data.
- Uses Reagent
- Functional MVC framework, uni-directional Data Flow
- Architecturally, re-frame implements "a perpetual loop"
- re-frame puts all application state into one place, which is called
app-db
. Single source of truth - Behaviours as pure functions without side effects
- Events are UI's Intent
- Effects and CO-Effects (add timestamp to all db effects)
- All app-data is in one Giant Atom DS
- Interceptors - middleware
- https://en.wikipedia.org/wiki/Event-driven_finite-state_machine (opens new window)
The six dominoes are:
- Event dispatch, the user clicks a button, or a websocket receives a new message.
:on-click #(re-frame.core/dispatch [:delete-item item-id])])
- Handling Events
- Effect handling, send logs/erros to reporting service, email, api calls
- Query
- View
- DOM
Data
Data Oriented Design Its about DATA and not functions. If data changes, view changes reactively
Events are data. Effects are data. DOM is data. The functions which transform data are registered and looked up via data. Interceptors (data) are preferred to middleware (higher order functions). Etc.
How do I query information model of app
In REPL, re-frame.db/app-db
, or in JS console window.re_frame.db.app_db.state
How to dispatch multiple events and how to cordinate between them?
Dependency b/w event dispatch?
How to deal with async calls and Promises?
(-> (js/Promise.resolve 42)
(.then #(js/console.log %))
(.catch #(js/console.log %))
(.finally #(js/console.log "cleanup")))
How to add Event Handler to a DOM Element?
Several ways
- Vanilla JS Interop
(defn handler [] (js/console.log "ready"))
(js/document.addEventListener "DOMContentLoaded" handler)
- Use Event Listener API by Google Closure library for cross browser compatibility
- Use 3rd party libraires like
react
,vue
,jQuery
etc,reagent
,reframe
- Google Closure Library is automatically bundlesd with cljs
- build external/foreign js usinf
{:optimizations :none}
then clojure can read symbols using js interop - cljsjs
How do I mount new components in SPA on-click?
reagent.dom/render (opens new window)
(reagent.dom/render [simple-component] (.-body js/document)))