Skip to content

Track children and parent within Components #576

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
lukeed opened this issue May 7, 2017 · 9 comments
Closed

Track children and parent within Components #576

lukeed opened this issue May 7, 2017 · 9 comments

Comments

@lukeed
Copy link
Member

lukeed commented May 7, 2017

It'd be useful to have access to the children Components from a parent-type. One could easily & directly alter child states (without affecting Parent state).

Similarly, it might be beneficial to add an additional _parent key to each component. Doing so allows children to set observers on the parent's state/internal values. Plus it adds an alternative path for communicating between child:parent without the need for custom events.

A few days ago, I had a little bit of time to read thru the source. I found that all the children data was available here and here during the compilation step. I didn't have enough time to follow up with the output generation. 😿

@PaulBGD
Copy link
Member

PaulBGD commented Jul 11, 2017

For accessing a child's properties, couldn't you just use the ref? https://svelte.technology/repl?version=1.25.0&gist=ee1e3ef7339bcbb2b6dc322bed7d5ab3

As for accessing the parent, in my opinion that's really really ugly. I think the parent should be the one to allow the child to access their state, which is actually really easy with something like bind: https://svelte.technology/repl?version=1.23.4&gist=ce14b1187c7e2c8a27332e77d226f0b8

@jslegers
Copy link

jslegers commented Aug 7, 2017

For accessing a child's properties, couldn't you just use the ref? https://svelte.technology/repl?version=1.25.0&gist=ee1e3ef7339bcbb2b6dc322bed7d5ab3

Suppose I have a DataTable component, which uses a Table component, which uses a TableRow component, which uses a TableCell component, which uses a TableCellInput component.

If I want to do something with the value of a TableCellInput component from my DataTable component, I would need to use something like this.refs.table.refs.row[y].refs.cell[x].refs.input.value. That's not exactly an elegant way to approach this.

As for accessing the parent, in my opinion that's really really ugly. I think the parent should be the one to allow the child to access their state

It would at least be nice to trigger an event in my TableCellInput component and have it bubble / propagate all the way to the DataTable component. That way, I could emit an event at the TableCellInput level whenever a value is changed and capture the event at the DataTable level to validate my input, update the database, etc.

Is this currently supported (without using DOM events)?

Anway, see also #11 (comment)

@PaulBGD
Copy link
Member

PaulBGD commented Aug 7, 2017

I think there's an issue for sending events to the parent more easily, but I can't quite find it.

I would need to use something like this.refs.table.refs.row[y].refs.cell[x].refs.input.value. That's not exactly an elegant way to approach this.

100% that's an ugly way to handle it. Basically the situation in this case is that the DataTable and the TableCellInput both share the same state. In my opinion, that's where you start using some sort of shared state library. I suppose a built in way would be to pass a components state among its children, but I could see that being ugly.

@jslegers
Copy link

jslegers commented Aug 8, 2017

I think there's an issue for sending events to the parent more easily, but I can't quite find it.

Propagating events between ancestors and descendants (passing along the state info) seems to me to be the most elegant approach.

I think there's an issue for sending events to the parent more easily, but I can't quite find it.

Propagating events between ancestors and descendants (passing along the state info) seems to me to be the most elegant approach.

I definitely don't see how sharing state in yet a different library / component is a better approach!

@Conduitry
Copy link
Member

These sorts of ideas (if not this specific ticket) have had quite a while to brew now - and I think we're pretty comfortable in our decision to support a parent instance having access to child instances (made more powerful in v3 via dynamic refs) and to not give a child direct access to its parent. Closing.

@jslegers
Copy link

jslegers commented Mar 22, 2019

So what about my use case (which I'll restate below)?

Suppose I have a DataTable component, which uses a Table component, which uses a TableRow component, which uses a TableCell component, which uses a TableCellInput component.

Now, suppose I want to observe any changes in any TableCellInput of my DataTable at the DataTable level rather than at the TableCellInput. For example, suppose I want my DataTable to keep (1) track of user input, (2) trigger a valueChanged event at the DataTable level when a value changes, (3) trigger validation, (4) optionally send a PUT or PATCH request with all values in that particular TableRow to update the data in my dataStore on the server (if validation succeeds) and then (5) optionally reposition the TableRow in the Table if (the field that's been changed is a field that's being sorted on).

What would be the proper way to do that in Svelte?

Or to rephrase my question : how do I deal with observing changes to the properties of deeply nested components? Adding individual observers to every this.refs.table.refs.row[y].refs.cell[x].refs.input.value where x and y are respectively the column positions and row positions doesn't seem quite efficient to me. Also, I can't exacly say it looks very elegant!

I suppose a whole lot more elegant approach than a whole bunch of observers would by be to trigger an event in my TableCellInput component and have it bubble / propagate all the way to the DataTable component. That way, I could emit an event at the TableCellInput level whenever a value is changed and capture the event at the DataTable level. However, I don't think that's currently supported, right?

@Rich-Harris
Copy link
Member

@jslegers The context API is your friend

@Rich-Harris
Copy link
Member

(note — that tutorial is currently broken due to a new Mapbox GL version #2297)

@jslegers
Copy link

@jslegers The context API is your friend

Awesome!

Will definitely check that one out next time I give Svelte a try...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants