Commit 1aaecd68 authored by Alex Sarmanov's avatar Alex Sarmanov

ajax rum mixin (cljs-ajax version)

parent 99d061a0
......@@ -3,9 +3,20 @@
[rum.core :as rum]
[redux.core :as r]
[utils.sys :as sys]
[utils.mixins :as mixins]
[clojure.data :as cldata]
[components.state-history :as state-history]))
(rum/defcs user-info < (mixins/ajax-mixin
"http://ip.jsontest.com/"
:get
{}
::user)
[state]
(if-let [user @(::user state)]
[:div (str "Your ip is: " (:ip user))]
[:div "Loading..."]))
(rum/defc index-page < rum/reactive []
"Root rum/react component"
(let [state (rum/react r/!state)]
......@@ -13,6 +24,7 @@
[:div "[" (:count state) "] " (pr-str (:message state))]
[:div
[:button {:on-click #(r/dispatch! {:type :mount-page :page :about :params {:aaa "xxx"}})} "To About page"]
(user-info state)
[:div (state-history/state-history)]
[:pre.state "current state: " (str @r/!state)]
;; [:pre "actions: " (str @r/!actions-history)]
......
(ns utils.mixins
(:require
[rum.core :as rum]
[utils.sys :as sys]
[ajax.core :refer [ajax-request
url-request-format
json-response-format]]))
;; (ajax-mixin "/api/users" :post {:id 1} custom-handler-function)
(defn ajax-wrapper
[uri method params handler]
(ajax-request
{:uri uri
:method method
:params params
:handler handler
:format (url-request-format)
:response-format (json-response-format {:keywords? true})}))
(defn ajax-mixin [url method params key]
{ :will-mount
(fn [state]
(let [*data (atom nil)
comp (:rum/react-component state)]
(ajax-wrapper
url
method
params
(fn [[ok response]]
(reset! *data response)
(rum/request-render comp)
))
(assoc state key *data)))})
;; This mixin can be used to remember the state of a component.
;; For this to work you need to UNIQUELY identify your component somehow.
;; For instance, by generating some unique id from the given args to your component:
(defn remember-state-mixin
"Remembers the state :rum/local for a given component and swaps it back on mount.
The given function is passed the args of the component (with apply).
And should return a map key that is used to uniquely identify the component.
(remember-state-mixin (fn [arg1 arg2] (:db/id arg1)))"
[f]
(let [store (atom {})
key-fn (fn [state] (apply f (:rum/args state)))]
{:will-unmount
(fn remember-state-unmount [state]
(swap! store assoc (key-fn state) @(:rum/local state))
state)
:will-mount
(fn remember-state-mount [state]
(let [old-state @store
key (key-fn state)]
(swap! (:rum/local state) merge (get old-state key {})))
state)}))
(ns utils.sys
(:require [redux.core :as r]
[clojure.data :as cldata]))
[clojure.data :as cldata])
(:import
[goog.net XhrIo]))
(defn indexed-vector [vec]
"Return [a b] vector with indexes [[0 a] [1 b] ...]"
......@@ -16,6 +18,7 @@
(last (nth indexed-state index1))
(last (nth indexed-state index2)))))))
;; deprecated, use secretary functions
(defn query-to-map [req]
"Convert ?xxx=zzz&aaa=bbb to map {:xxx zzz :aaa bbb}"
(into {} (for [[_ k v] (re-seq #"([^&=]+)=([^&]+)" req)]
......@@ -26,3 +29,14 @@
(let [query-params (:uri (:url r/!state))]
(js/console.warn query-params)
(query-to-map query-params)))
(defn rand-n [min max]
(+ min (rand-int (- max min))))
(defn rand-pred [pred f]
(let [x (f)]
(if (pred x) x (recur pred f))))
(defn later [f]
(js/setTimeout f (rand-n 1000 2000)))
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment