Fork me on GitHub
#untangled
<
2017-04-15
>
tony.kay00:04:14

so, when you “populate” a form, yes, you’d have to populate the controls with the data in question. So, clicking on the date to trigger the calendar “picker” would copy the date from your entity into the component, and a callback on that component would be hooked up (by the parent) to copy the result back on “commit” (via a transact). That’s not really much different from other pre-built components in other systems. You don’t “overlay the concept” of a date with a calendar UI widget…you hook up a callback that tells you what date got chosen, and if you want to pre-feed it with a date you do that beforehand (I don’t know all frameworks, but this does seem the norm to me).

urbank07:04:02

@tony.kay Yes, you're right, I think it is the norm. However, I'm a bit paranoid that I'll come upon a case where this will become more of a problem. As long as the editing component is hidden while not used (like calendar in a popup), it's very simple to update it every time it opens. But if the calendar is always visible, and in two places at the same, editing/displaying the same value, it does have to be updated every time the value changes for whatever reason.

urbank07:04:33

So I've been playing with the idea of all components converting entity data into form data on the fly. That way, the component has no representation in the state, but just converts the entity data that it's editing to fit its internal model of what that data should look like, so that it's digestible by the edit component.

urbank07:04:12

So a calendar would get some date passed into it as props

urbank07:04:14

It would display the month of that year, with the day highlighted, and when another day was clicked, it would just send the new date to the callback, and the callback would update the entity. On rerender, there the calendar would automatically get the new date in the target entity as props. So would all the other calendar components targeting the same entity.

urbank07:04:30

Sound a bit contrived, perhaps

tony.kay15:04:16

@urbank not contrived at all..that is the model of untangled-ui’s forms support 🙂

tony.kay15:04:07

it is an extensible system where you add a new form-field type (with field constructor), and then add a renderer for that type (to a multimethod).

tony.kay15:04:45

could be a map for selecting regions, a calendar for selecting dates, etc. The caveat is that if it has some data needs, (beyond the field itself) then it uses component local state.

tony.kay15:04:15

well, technically you could “program” it to use normalized data by giving it an ID and using dynamic queries to set the component’s query and point it at the “right state”,

tony.kay15:04:17

that latter bit would probably be more cumbersome than you’d care to deal with for such a simple concern (losing support viewer visibility during the field edit)

tony.kay15:04:05

and I’ve not even written anything about dynamic queries because this is honestly the first time I’ve found an example where I’d be tempted to try one in the Untangled model.

tony.kay16:04:20

Side note: In fact, dynamic queries add so much overhead and complexity to applications and the internals of Om Next that I’d vote for eliminating them entirely. I cannot think of a single use-case where Untangled actually needs them in a way where the benefits outweigh the costs. Their existence means that every time a query is run Om Next must go through that result and query again and mark all of the bits with query path data, and then also index the components by that path information (it’s how to keep track of what parts of the query has been changed). This nearly doubles the overhead in my measurements for each animation frame. OK, so what do you get out of dynamic queries: 1. a way to do UI routing (easily doable with union queries instead, which is a feature that has no real performance penalty and adds no more complexity to your code). 2. A way to add data parameters to your query (more easily implemented as data in the entity’s app db state, avoiding the complexity of having to write a parser for the query). 3. A way to arbitrarily change the query for some other concern (the above-mentioned, hacking a non-user-defined component into the tree on the fly, which is difficult to structure because you need to change the parent’s query). This 3rd one is the only one I consider possibly advantageous. It also enables things like dynamic code loading (modules) where you don’t know about the query/components in advance.

tony.kay16:04:16

Hm. actually now that I think more about it, you would not use a dynamic query for the form example. You’d just document that they should mix the form field’s UI query into the parent once for each field ID.

tony.kay16:04:04

So, that brings it down to dynamic code loading (modules). Seems like it’d be nice to have the ability to turn off dynamic query support and avoid the overhead.

tony.kay16:04:55

actually, we’re in javascript…you can redefine things on the fly. Perhaps the loaded module “overwrites” the component that links it in with a new component (that has a new query). Interesting possibility. Om.N. would have closed over the root component (with the old leaf composed into the query), though. You’d probably have to unmount/mount, but React would prevent flicker…might be some React hacking; not sure how to leave the DOM in place during that operation.

urbank21:04:26

@tony.kay So is dynamic queries IQueryParams? I assume it's just setting a different query to a component dynamically. So I suppose I'll try digging into form support again, because I think I got stuck last time because I was tacking it onto an example app that had begun when I was less aware of the philosophy behind untangled. Since the rewrite isn't projected for the immediate future, I suppose I'll write a couple of prototypes with a few different approaches/libs and see what suites the app most. As always, thanks for the meaty(?) replies 🙂