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.

Reply via email to