Skip to content
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

Feature: Dynamic ref: names #881

Closed
btakita opened this issue Oct 4, 2017 · 5 comments
Closed

Feature: Dynamic ref: names #881

btakita opened this issue Oct 4, 2017 · 5 comments

Comments

@btakita
Copy link
Contributor

btakita commented Oct 4, 2017

I'd like to reference a component in an #each block. To do so, I propose a feature to dynamically set the name of the ref using escaped variables. Is this a good idea? Is there a better alternative?

{{#each items as item}}
<Subcomponent ref:item__{{item.name}}></Subcomponent>
{{/each}}
@Rich-Harris
Copy link
Member

The alternative we'd discussed was to create an array of refs, so this...

{{#each items as item}}
  <Subcomponent ref:item></Subcomponent>
{{/each}}

...would result in this:

console.log(component.refs.items); // [Subcomponent, Subcomponent, Subcomponent]

The advantage of that approach is that you can do refs.items.forEach etc. But it's maybe a bit odd that refs.x is sometimes a component, and sometimes an array, and you have less control over how it's structured — it could get confusing if you had refs inside an each inside an each.

I wonder if there's a third option worth considering:

{{#each items as item, i}}
  <Subcomponent ref:items[i]></Subcomponent>
{{/each}}

In that case, we're explicitly opting in to refs.items being an array. What do you reckon?

One wrinkle — we'd probably want refs.items to be an object if we did this instead:

{{#each items as item}}
  <Subcomponent ref:items[item.name]></Subcomponent>
{{/each}}

Not sure how best to handle that distinction.

@btakita
Copy link
Contributor Author

btakita commented Oct 5, 2017

I personally think the ideal is to have an explicit reference in the code, without an implicit name translation.

So, IMO, I like the 2nd & 3rd options that you presented.

{{#each items as item, i}}
  <Subcomponent ref:items[i]></Subcomponent>
{{/each}}
{{#each items as item}}
  <Subcomponent ref:items[item.name]></Subcomponent>
{{/each}}

It seems like items would be referenced by name, so the first level of the graph can be a name. If you are doing a lexical scan; if i is the index from item, i make refs.items an Array else Object?

Another factor to consider is supporting a n-level hierarchy...

{{#each parents as parent, i}}
  {{#each items as item, j}}
    <Subcomponent ref:parents[i].items[j]></Subcomponent>
  {{/each}}
{{/each}}
{{#each parents as parent}}
  {{#each items as item}}
    <Subcomponent ref:parents[parent.name].items[item.name]></Subcomponent>
  {{/each}}
{{/each}}

@Conduitry
Copy link
Member

There might be some value in the React perspective on refs, which is: deprecate named refs, and have all refs be functions which are passed the element, and which do whatever the developer wants with it. In Svelte, these could be sort of an 'on create' type of event handler, and which would have access to the element/component instance (via some special name) and which also has access to all of the values on the scope at that point (including, for example, each block variables or indexes).

@aseem2625
Copy link

Any update on this settings ref to dynamically rendered components?
Need to trigger events on each item.

@Conduitry
Copy link
Member

bind:this can accept dynamic expressions to bind to in v3, but I don't see an example of it currently in the docs. Closing this, and opening another issue for the docs.

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

No branches or pull requests

5 participants