To be clear:
(defn child-comp [cursor]
(reify
om/IRender
(render [_]
(dom/div nil
(dom/div nil (:foo cursor)) ; This is still a cursor and you can
call update or transact on it
(dom/div nil (:bar cursor)))))) ; This is NOT a cursor
(defn parent-comp [cursor]
(reify
om/IRender
(render [_]
(om/build test-comp {:foo cursor :bar [1 2 3]}))))
This makes sense and it couldn't really be any other way because in
Clojure, everything is immutable by default and if something-else doesn't
live in the app-state atom, then what would you be modifying with update or
transact? If you pass a cursor or index into a cursor, it will still be a
cursor when the child gets it.
On 10 October 2014 10:16, Stephen Wakely <[email protected]> wrote:
> Thanks. So it looks like without using the domain data, you can only pass
> data down the component tree. Passing data back up would then need
> core.async.
>
> I like the option 2 you have suggested. It is unfortunate that it then
> turns the cursor into a plain atom. What would be handy is if we could call
> (om.core/to-cursor (om.core/setup my-atom)) or some equivalent on this
> atom, which should then (in theory) enable modifying the parents state. We
> could then create local areas of domain data for these sub components.
>
> Unfortunately these functions are declared as private within Om, so there
> is probably a reason why this isn't as straight forward as I imagine.
>
>
>
>
>
>
> On 10 October 2014 08:39, Daniel Kersten <[email protected]> wrote:
>
>> I personally like keeping the incidental local state local to components
>> and keep the app state purely for domain data. Therefore I would use the
>> local state like you said and use the cursor only to point at the tag list
>> being modified.
>>
>> As for how to manage the local state with sub components, you basically
>> have two options (not including core.async):
>> 1. You can use :init-state and :state in the om/build options to pass
>> state to the child component
>> 2. You can add additional data to the child components cursor, eg:
>> (om/build tag-component {:extra-data foo :tag (:tag cursor)})
>>
>> Since the child component is private, you could put whatever local state
>> you want into the cursor without exposing it to the user of your component.
>> Note that you won't be able to call update or transact on this additional
>> data, so you won't be able to directly modify the parents state. You could
>> use a callback or core.async to communicate with the parent.
>>
>> I use the first option where possible and the second if the state is part
>> of the domain data from the child's perspective (but in reality is
>> generated by the parent) - usually when the child isn't private.
>> On 10 Oct 2014 00:05, "Stephen Wakely" <[email protected]> wrote:
>>
>>> I've just finished writing my first Om component (
>>> https://gist.github.com/FungusHumungus/aa6527505c24f7e2c83f). I have a
>>> sneaky suspicion that I have gone the wrong way about it, and would like to
>>> know what a more idiomatic way to develop this component would be.
>>>
>>> The component is a simple Tag selector. The user can enter multiple tags
>>> and choose them from an auto complete list - similar to the tag entry field
>>> on stack overflow.
>>>
>>> Because this is a component, I don't want it to pollute the global
>>> application state. It should only mutate one field - the tag list. There is
>>> a lot of other state that this component needs to maintain - the choices in
>>> the autocomplete list, the currently selected item, the currently entered
>>> text.
>>>
>>> I am not sure what the best way to maintain this other state should be.
>>> The way I have approached it is to use the component state. The problem
>>> with this is that I am then prevented from creating other sub components
>>> easily. It seems the component structure needs to map onto the global app
>>> state via cursors in order to handle the needs updating event.
>>>
>>> So rather than creating separate components, I have one big component
>>> and am just creating standard Clojure functions that create the various dom
>>> components as necessary. The owner and cursor of this component gets passed
>>> around an awful lot. This doesn't feel tidy.
>>>
>>> I'm pretty sure one disadvantage of having one big component rather
>>> than multiple nested controls is that for every change in the state, the
>>> whole control would need to be rebuilt. I realise React does help a lot
>>> here by maintaining its own copy of the Dom, so really minimal aspects of
>>> the Dom are changed - but I am still looking to find the best solution from
>>> the start.
>>>
>>> I have been thinking using core.async channels to share state between
>>> the controls might be an alternative, but I'm not convinced it would be
>>> more efficient.
>>>
>>> Is there a better way?
>>>
>>> Thanks
>>>
>>>
>>>
>>> --
>>> 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.
>>>
>> --
>> 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.
>>
>
> --
> 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.
>
--
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.