diff --git a/modules/reitit-frontend/src/reitit/frontend/controllers.cljs b/modules/reitit-frontend/src/reitit/frontend/controllers.cljs index 02024919..9b11bb5b 100644 --- a/modules/reitit-frontend/src/reitit/frontend/controllers.cljs +++ b/modules/reitit-frontend/src/reitit/frontend/controllers.cljs @@ -1,4 +1,5 @@ -(ns reitit.frontend.controllers) +(ns reitit.frontend.controllers + "Provides apply-controllers function") (defn- pad-same-length [a b] (concat a (take (- (count b) (count a)) (repeat nil)))) @@ -10,6 +11,25 @@ (if-let [f (:params controller)] (f match))) +(def static + "Static params means that the identity of controller + doesn't not depend on Match, i.e. any parameters. + + This is same as just not defining :params." + nil) + +(defn parameters + "Given map of parameter-type => list of keys, + returns function taking Match and returning + value containing given parameter types and their + keys. + + The resulting function can be used for :params." + [p] + (fn [match] + (into {} (for [[param-type ks] p] + [param-type (select-keys (get (:parameters match) param-type) ks)])))) + (defn apply-controller "Run side-effects (:start or :stop) for controller. The side-effect function is called with controller params." @@ -19,8 +39,8 @@ (defn apply-controllers "Applies changes between current controllers and - those previously enabled. Resets controllers whose - parameters have changed." + those previously enabled. Reinitializes controllers whose + identity has changed." [old-controllers new-match] (let [new-controllers (mapv (fn [controller] (assoc controller ::params (get-params controller new-match))) diff --git a/modules/reitit-frontend/src/reitit/frontend/history.cljs b/modules/reitit-frontend/src/reitit/frontend/history.cljs index 35d8a091..4ec295fa 100644 --- a/modules/reitit-frontend/src/reitit/frontend/history.cljs +++ b/modules/reitit-frontend/src/reitit/frontend/history.cljs @@ -1,4 +1,6 @@ (ns reitit.frontend.history + "Provides integration to hash-change or HTML5 History + events." (:require [reitit.core :as reitit] [reitit.core :as r] [reitit.frontend :as rf] diff --git a/test/cljs/reitit/frontend/controllers_test.cljs b/test/cljs/reitit/frontend/controllers_test.cljs index 27a44ff6..b0acb600 100644 --- a/test/cljs/reitit/frontend/controllers_test.cljs +++ b/test/cljs/reitit/frontend/controllers_test.cljs @@ -64,5 +64,46 @@ (is (= [[:stop-3 1] :stop-1] @log)) (is (= [] @controller-state)) + (reset! log [])))) + +(deftest controller-data-parameters + (let [log (atom []) + controller-state (atom []) + static {:start (fn [params] (swap! log conj [:start-static])) + :stop (fn [params] (swap! log conj [:stop-static])) + :params rfc/static} + controller {:start (fn [params] (swap! log conj [:start params])) + :stop (fn [params] (swap! log conj [:stop params])) + :params (rfc/parameters {:path [:foo]})}] + + (testing "init" + (swap! controller-state rfc/apply-controllers + {:data {:controllers [static controller]} + :parameters {:path {:foo 1}}}) + + (is (= [[:start-static] + [:start {:path {:foo 1}}]] @log)) + (is (= [(assoc static ::rfc/params nil) + (assoc controller ::rfc/params {:path {:foo 1}})] + @controller-state)) (reset! log [])) - )) + + (testing "params change" + (swap! controller-state rfc/apply-controllers + {:data {:controllers [static controller]} + :parameters {:path {:foo 5}}}) + + (is (= [[:stop {:path {:foo 1}}] + [:start {:path {:foo 5}}]] @log)) + (is (= [(assoc static ::rfc/params nil) + (assoc controller ::rfc/params {:path {:foo 5}})] + @controller-state)) + (reset! log [])) + + (testing "stop" + (swap! controller-state rfc/apply-controllers + {:data {:controllers []}}) + + (is (= [[:stop {:path {:foo 5}}] + [:stop-static]] @log)) + (reset! log []))))