On Tuesday, April 21, 2015 at 10:58:31 PM UTC+10, Colin Yates wrote:
> Hi Mike - yeah, reading through I wasn't very clear. Let me try again
> with a more fleshed out example:
>
> On the server there is a hierarchy, each node in that hierarchy may
> contain some meta data for example:
> :id - the unique id of the node
> :type - indicating some semantics about that particular node
> :current? - indicating whether it is still actively used or not
>
> Imagine there are 5 nodes and node 4, which is a leaf is not :current?.
>
> On the client I have a number of projections of this data:
> - an "active" tree which prunes out all nodes that aren't :current?,
> so there are 4 nodes
> - an "everything" tree which shows everything, e.g. all 5 nodes
>
> In addition, every node in each tree is selected and there are
> multiple instances of these trees.
>
> On the client (on a reporting page for example, where one of these
> trees are in the filter) I need to know which nodes the user has been
> selected. I have a handler, which in response to some event (either
> the server indicating new data is available or the user changing some
> data) which needs to know which nodes have been selected.
>
> If the user hasn't selected anything then the 'selected nodes' should
> be the default set (i.e. all of the nodes). As soon as the user
> changes the selection (by deselecting a node in the first instance)
> the set of selected nodes is now every node that is selected (e.g.
> every node apart from the one they just selected) and that instance of
> the tree is no longer tracking the defaults.
>
> The server is free to send new config data at any point in time. When
> this happens, the default set should be updated. The non-default set
> that the user has changed should also be consolidated as well, but
> that is different.
>
> Lets say my app state looks like:
>
> {:page-1 {:some-active-tree {:selected-ids [] :tracking-default? true}
> :another-active-tree {:selected-ids [] :tracking-default?
> true}
> :some-all-tree {:selected-ids [] :tracking-default? true}}
>
> The user hasn't done anything so the selected-ids should be the
> default sets (4 ids for :some-active-tree and :another-active-tree and
> 5 ids for :some-all-tree). If the user were now to deselect node 2 in
> :another-active-tree then app-state looks like:
>
> {:page-1 {:some-active-tree {:selected-ids [] :tracking-default? true}
> :another-active-tree {:selected-ids [0 1 3]
> :tracking-default? false}
> :some-other-tree {:selected-ids [] :tracking-default? true}}
>
> If they deselect node 3 in some-other-tree:
>
> {:page-1 {:some-active-tree {:selected-ids [] :tracking-default? true}
> :another-active-tree {:selected-ids [0 1 3]
> :tracking-default? false}
> :some-other-tree {:selected-ids [0 1 2 4]
> :tracking-default? false}}
>
> Should the server now update the config hierarchy changing node 4 back
> to :current? and adding another node then at the very least the
> 'selected nodes' for :some-active-tree should contain the ids of all 6
> nodes. :another-active-tree and :some-other-tree should also be
> informed but they might not be updated depending upon the selections
> (it gets more complicated...).
>
> At this point it is clear that one solution is to record a delta from
> the defaults, but that only works because we are talking about
> booleans; there are other non-boolean use-cases unfortunately.
>
> Another solution is to store the sets of defaults in app-state itself
> rather than have it be a subscription and then overtime it changes
> update the affected parts of app-state (:some-tree and
> :some-other-tree in this example).
>
> This would be much easier if it was just dealing with rendering data,
> in which case subscriptions are a perfect fit, but the set of data
> needs to be sent back to the server periodically in a handler, and
> handlers can't see subscriptions.
>
> To be frank, if anyone is still reading, my experience tells me that
> if the problem is this hard to explain and requires this much
> explanation then _I_ haven't understood it properly :), so I think I
> need some more hammock time is in order.
>
> Thanks for anybody who hasn't lost the will to live yet ... :).
>
> On 21 April 2015 at 13:08, Mike Thompson <[email protected]> wrote:
> > On Tuesday, April 21, 2015 at 4:52:05 AM UTC+10, Colin Yates wrote:
> >> Hi,
> >>
> >> This is somewhat reframe specific, but how do people handle default-values
> >> that can change? My specific use-case is that I have a tree which can be
> >> expanded and collapsed. By default the tree should be expanded to a
> >> certain level, however, as soon as the user manually expands or collapses
> >> a node they should no longer follow the default. The data the tree is
> >> displaying can change, meaning the defaults can change over time.
> >>
> >> I can't simply define the defaults on startup because the defaults will
> >> change over time.
> >>
> >> It can't be a subscription because the values need to be available in the
> >> handler.
> >>
> >> My current thinking is that the app-db state has a 'follow-defaults?'
> >> which is true by default but is set to false when the user explicitly
> >> changes the state (e.g. by expanding or collapsing). When the underlying
> >> hierarchy changes from the server, propagate that change to all of the
> >> parts of the app-state that are interested.
> >>
> >> To be explicit, imagine I have the following template for tree:
> >> {:expanded-ids [] :follow-defaults? true}. There are 6 instances of this
> >> template in the app-db (i.e. 6 distinct UI trees). When the server
> >> informs the client that the source-data has changed it then updates each
> >> instance where follow-defaults?.
> >>
> >> I understand the rationale as to why subscriptions can't be in the
> >> handlers but a subscription which switches on follow-defaults? seems ideal.
> >>
> >> Maybe I could hack a UI-less component which reacts to that subscription
> >> change by directly updating the underlying db...
> >>
> >> What would you all do?
> >
> >
> > Hi Colin,
> >
> > I'm not sure I'm clear on the problem. Here's my attempt to explain back ...
> >
> > You have some setting (data) in your app (tree display state) which can be:
> > 1. in a server-supplied state (you call this "default" state?)
> > 2. optionally, in user-supplied state (if present, overrides 1).
> >
> > Over time, new versions of 1. arrive. If 2. exists, it always overrides 1.
> >
> > Have I understood?
> >
> > --
> > Mike
Hmm. I don't get the specifics, but maybe we can talk abstractly ...
You have values a and b which can change over time. And you have another value
c which is a function (f) of a and b.
(f a b) => c
And, a b and c are all stored in `app-db`.
And then when, say, 'a' gets updated (server? user?), you want to (reactively)
modify the value in c again. After all, its value is a function of a and b,
and a just changed?
And you are reaching for `subscribe` as a way to sorta know when to rerun 'f'
to recalculate new 'c'.
Have I got it now?
--
Mike
--
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.