How to call child component method from parent component with foreach

可紊 提交于 2020-08-10 08:40:10

问题


I've seen examples of how to call a child component's method from a parent component using the @ref attribute, but when I try to use it with a foreach loop, only the last rendered component's method gets called and not all of them. Below are examples of my components.

Parent component:

<button type="button" class="btn btn-link" @onclick="BtnSyncAll_Click">Run<button>

@foreach(var site in Sites)
{
    <Site @ref="SiteView" @Code="@site"></Site>
}

@code {
    protected Site SiteView;
    protected List<string> Sites { get; set; } = new List<string>
    {
        "A00001",
        "A00002"
    };

    protected async Task BtnSyncAll_Click()
    {
        await SiteView.Sync();
    }
}

Child component (Site.razor):

<div>
    <p>@Code>/p>
</div>

@code {
    [Parameter]
    public string Code { get; set; }

    protected async Task Sync()
    {
        await ...
    }
}

回答1:


Both you and enet are overcomplicating things...

The most "politically correct" approach to do what you pretend may be creating an independent service to signal every child component when has to resync, and inject it by means of DI, but this would take too much plumbing for this, and maybe in your case it's not worth it. So here you have a simpler approach:

First, remove the Sync method from your component, change it for this:

[Parameter]
public int SyncSignaler { get; set; }


protected override async Task OnParametersSetAsync()
{
    await Task.Delay(300);
    output = $"This is Site: {Code}";
    //StateHasChanged();
}

Then, declare a integer variable on your parent component, pass it to the childs, and increment it every time you want them to refresh.

In your parent component:

@foreach (var site in MySites)
{
    <Site Code="@site.Code" SyncSignaler="@syncIndicator"></Site>
}


@code {
 
    private int syncIndicator = 0;

    protected async Task BtnSyncAll_Click()
    {
        syncIndicator++;
        StateHasChanged();
    }

etc...

Please, let me know if it worked. Cheers!




回答2:


Here's a code sample describing how you should do it:

Site.razor

<div>
    <p>@Code</p>
</div>
<p>@output</p>

@code {
    [Parameter]
    public string Code { get; set; }
    private string output;
    private static int index;

    public async Task Sync()
    {
        await Task.Delay(300);
        output = $"This is Site: {Code}";
        StateHasChanged();
    }
}

Usage

<button type="button" class="btn btn-link" @onclick="BtnSyncAll_Click">Run</button>

@foreach (var site in MySites)
{

    <Site @ref="@site.SiteRef" Code="@site.Code"></Site>
}

@code {
     private List<MySite> MySites;

    protected override void OnInitialized()
    {
        MySites = new List<MySite> { new MySite { Code = "A00001", SiteRef = new Site() },
                                                 new MySite { Code = "A00002", SiteRef = new Site()} };
    }

    protected async Task BtnSyncAll_Click()
    {
        foreach (var site in MySites)
        {

            await site.SiteRef.Sync();
        }


    }

    public class MySite
    {
        public string Code { get; set; }
        public Site SiteRef { get; set; }
    }

Hope this helps...



来源:https://stackoverflow.com/questions/62519575/how-to-call-child-component-method-from-parent-component-with-foreach

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!