As others have replied, storing *reified* components is usually a mistake. I
tend to think of it like this:
- app-state is the global, stateful model which is owned, updated and managed
by you
- components are transient and are owned, updated and managed by om
When it comes to nesting, the two approaches seems to be:
- multimethods (see the 'basic' documentation)
- passing vars around in app-state or component-state
After going down this rabbit hole I am of the opinion that multi-methods are
your friend first of all.
For your specific use-case, I have the exact same need and solved it as follows:
- store the page-key in app-state (literally a keyword indicating the stage)
- switch on that key to chose the component to render (either multi-method or
simple condp =.
For example:
(ns my.page-1) (defn page [cursor owner] (om/component (dom/div nil "Hi there
page 1")))
(ns my.page-2) (defn page [cursor owner] (om/component (dom/div nil "Hi there
page 2")))
(ns my.page-3) (defn page [cursor owner] (om/component (dom/div nil "Hi there
page 3")))
In main:
(ns my.main
(require [my.page-1 :as p1]
[my.page-2 :as p2]
[my.page-3 :as p3])
(defn om-root [app-state owner]
(om/build
(condp = (:page app-state)
:page-1 p1/page
:page-2 p2/page
:page-3 p3/page)))
and then mount om-root. Changing page is as simple as changing the value of
:page in app-state.
There are other approaches - rendering every 'page' but making them all hidden
except for the current one, but I like the simplicity of the above approach.
Even if you do have to handle things like remembering scroll positions etc. of
non-visible pages.
Hope this helps.
(which is also an excellent example of why multi-methods are so much nicer ;)).
On Sunday, 16 November 2014 08:08:09 UTC, David Mohl wrote:
> Hey Guys,
>
> I am very fresh to clojurescript and love it so far. I am in fact currently
> trying to build my first webapp using clojure and compojure for the backend,
> and om combined with secretary for the frontend, but I have a lot of issues.
>
> While I slowly get a grasp of om, I am trying to 'switch' pages (or views?)
> to give that feel of a responsive single-page app. To implement this, I
> 'thought' I could simply create a root-app which mounts my other views when I
> need them. Something like this:
>
> (defn default-view [app owner opts]
> (om/component (dom/h1 nil "Default View")))
>
> (defn root-app [app] (om/component (:view app)))
> (def app-state (atom {:view (om/build default-view root-app)}))
> (om/root app-state root-app (aget (.getElementsByClassName js/document
> "main") 0))
>
> Very simple. The root app gets mounted into the main div, and the root app
> mounts whatever is under :view inside the app-state. Works fine so far.
>
> I am access detail/1/, om mounts my detailview, the detailview mounts all the
> components that it needs, one of them loading ajax. Now here comes my
> problem, I am trying to use om/transact to change state. Something like:
>
> om/IInitState
> (init-state [_] (om/transact! app [:data] (fn [] [])))
>
> om/IWillMount
> (will-mount [_] (go (let [foo (<! (fetch-something))]
> (om/update! app #(assoc % :data foo)))))
>
> (I learned that from a example. (fetch-something) is doing a simple ajax call
> through core.async.)
>
> Now when executing I am getting: "No protocol method ITransact.-transact!
> defined for type function: function root_app(app){if(typeof picky.core.t16273
> !== 'undefined'). "
>
> This error tells me that ITransact is not implemented in my root_app which I
> used for building all the other components. So I must have done something
> wrong or the approach of using a root_app to mount everything else is simply
> not working.
>
> Anyone here who can point me into the right direction? Would appreciate any
> help
--
Note that posts from new members are moderated - please be patient with your
first post.
---
You received this message because you are subscribed to the Google Groups
"ClojureScript" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/clojurescript.