dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.46k stars 10.03k forks source link

Capture references to multiple similar child-components #13358

Open harleydk opened 5 years ago

harleydk commented 5 years ago

I was searching for documentation on how to capture references to child-components based on for-each creation. Let's say I have a parent-component which itereates a collection to create multiple child-components:

@foreach (var singleDataPiece in aCollectionOfData)
{
    <SubComponent Id="@singleDataPiece.Id" SingleDataPiece="@singleDataPiece"></SubComponent>
}

I would like to call a method on one of these sub-components, identified by its id-value. Would you consider adding documentation on this scenario?

Many thanks in advance for your consideration.

NTaylorMullen commented 5 years ago

@danroth27 @rynowak @SteveSandersonMS this is a real interesting ask that isn't currently possible with @ref. I'm not sold on the idea of allowing components to be looked up by ID but I could see it being valuable to overload @ref's capabilities with a List<TComponentType>.

The codegen would be slightly interesting but not impossible.

harleydk commented 5 years ago

I'm not sold on the idea of allowing components to be looked up by ID

Concerned it would lead to lack of developer discipline? Or goes against what you're trying to achieve with Blazor? I can appreciate any concerns along those lines. In my particular use-cases it would certainly ease the transition to Blazor from other frameworks. Always had the ability to identify a component, web or win, by a get-by-id or a view-children something-something, what or have you. Sure, there are ways around it, and I might lack dev discipline as much as any. But when dealing with N number of similar sub-components it can be an intuitive way to work. I digress, pardon me. I haven't spent enough time with this framework to consider alternatives to my issue. Ideally I would like to reference a sub-component based on an arbitrary (linq-style) expression - maybe that's already in there and I haven't looked hard enough.

danroth27 commented 5 years ago

@harleydk Thanks for this feedback! We've put this suggestion on our backlog. We don't have immediate plans to address this, but we will reconsider based on customer feedback. We would recommend modeling the behavior you want using your app model instead of trying to capture multiple references of child components.

harleydk commented 5 years ago

@danroth27 Great stuff. Closing this up. Have a good one.

danroth27 commented 5 years ago

@Harleydk We'd like to keep this feedback open on our backlog for a bit to see if anyone else runs into the problem. We may yet decide to do something in this area depending on user feedback.

Madhust commented 5 years ago

@danroth27 Angular has similar decorator ViewChildren which collects list of directive instances either by name or type.

https://angular.io/api/core/ViewChildren

It would be good to have such funtionality in Blazor.

RemiBou commented 5 years ago

+1 for this kind of feature : accessing child and/or parent components would be very helpful. I think right now you can do this with a cascading parameter (a list of component where the child component registers itself) but it's not easy.

mv10-work commented 5 years ago

Another vote. The List<TComponentType> idea seems intuitive enough.

Kahbazi commented 4 years ago

@harleydk For now you can use this workaround for getting a reference to the components in a loop.

@for (int i = 0; i < 10; i++)
{
    <MyComponent @ref="component"/>
}

@code
{
    MyComponent component { set => components.Add(value); }

    List<MyComponent> components = new List<MyComponent>();
}

I think you can also do a little Blazor Injection :smiling_imp: :smiling_imp:

@for (int i = 0; i < 10; i++)
{
    <MyComponent @ref="components.Add((MyComponent)__value);//" />
}

@code
{
    List<MyComponent> components = new List<MyComponent>();
}
ghost commented 3 years ago

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.

Dreamescaper commented 1 year ago

Since @ref is backed by AddComponentReferenceCapture method, which accepts a lambda, I suggest to add lambda "overload" to @ref directive, so that smth like that would be possible:

@for (int i = 0; i < 10; i++)
{
    <MyComponent @ref="r => components.Add(r)" />
}

@code
{
    List<MyComponent> components = new List<MyComponent>();
}
adamfoneil commented 1 year ago

I have a situation where I need to track the expand/collapse states of rows in a table. I tried using the List<T> approach, but the @ref thing is not allowing a lambda in .NET6, it seems. Maybe the new QuickGrid can do this in some way? Or there's something else entirely? My table is extremely dynamic, so I'm building from plain html. Therefore, I'm not seeing a good fit with off-the-shelf components like Radzen's Grid that allows row-level "expansion" toggling.

image

FilipVanBouwel commented 1 year ago

I could also really use this functionality. I have a blazor page where multiple Radzen Charts are displayed (variable, based on selection settings from the user). Every chart is bound to a data object in a list. The user also has some options for those charts (which data to display on which axis), so after changing these settings, I need to ReFresh each Radzen Chart by calling its Refresh() method (StateHasChanged does not update the Radzen Charts, you need to call the Refresh() method on every chart). So I need references to all Radzen Charts in the page for this. This is currently not possible with @ref.

nhwilly commented 1 year ago

And I have a MudBlazor MudChipSet that is data driven. Unfortunately, they don't let me access the list of MudChips in the MudChipSet, so I have to find a way to track it on my own. One of the above examples is working for now.

ghost commented 10 months ago

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.

mkArtakMSFT commented 10 months ago

@SteveSandersonMS @javiercn thinks that there may be a simple solution here utilizing a change on the compiler side. Maybe you two should sync up.