Yes, that is a valid reduction. Specifically my register-handler, which only has access to db needs to know the result of f.
The general principle of having my register-sub delegating to a defn which is called from the register-handler is causing the pain because there is actually a hierarchy of subscriptions going on here, so the value of f might actually be resolving a chain of subscriptions. For a simplified example: (register-sub :reference-data/locations) (register-sub :reference-data/active-locations .. (reaction (subscribe [:reference-data/locations)))) (register-sub :page-1/location .. (reaction (if (following-defaults? (-> db ...) @(subscribe [:reference-data/active-locations)))) the value of :page-1/location is of interest. On 21 April 2015 at 14:27, Mike Thompson <[email protected]> wrote: > 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. -- 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.
