how can I refer to a component created via DynamicComponent in Blazor?

Viewed 622

I'm rendering components using DinamicComponent and I need to call a function found in the child component. I can't find the equivalent of using @ref for the DinamicComponents so that I can reference to call the function.

This is the parent component

 <div class="tab-content">
            @foreach (VerticalTabComponent.TabModel oneTabItem in VerticalTabsList)
            {
                <div class="tab-pane fade show @(oneTabItem.TabIndex == SelectedTabIndex ? "active" : "")" @key=@($"VTabDivDynamic_{TabPrefix}_{oneTabItem.TabIndex.ToString()}")>
                    <DynamicComponent
                              Type=@System.Type.GetType(oneTabItem.TabComponent)
                              Parameters=@oneTabItem.TabParameters>
                    </DynamicComponent>
                </div>
            }
        </div>

This is the code in Blazor Component Tab

 public partial class TabComponent
{
    [Parameter]
    public EventCallback<string> InsertUpdateCallback { get; set; }

    
    protected override async Task OnInitializedAsync()
    {
       await CallAnyfunctionAsync();
    }
    private async Task<bool> LoadDataGrid()
    {
       //this is the function I need to call from parent
    }
}

How can I call the Load Grid function from the parent component?

2 Answers

There is an easy solution. Not sure if that is new but the ref-attribut does exist for the DynamicComponent! You can use it like this:

<DynamicComponent Type="typeof(MyComponent)" Parameters="@MyParameters" @ref="dc" />

and in Code-Behind:

private DynamicComponent? dc;

private MyComponent? MyComponentRef
{
    get
    {
        return (MyComponent?)dc?.Instance;
    }
}

Normally in Blazor we use @Ref to get a reference to a component, but as you've seen this won't work with a DynamicComponent.

A workaround for this would be to add a [Parameter] to the component called something like Register which is an action with the generic type set as the component type. You can then add code to handle OnParametersSet to call this method in the component.

You can then add a Register parameter in your TabParameters which gets updated with a reference.

Example code below would be added to the SurveyPrompt component:

    /// <summary>
    ///  will be called when params set
    /// </summary>
    [Parameter] public  Action<SurveyPrompt> Register { get; set; }

    protected override void OnParametersSet()
    {
        if (Register != null)
        {
            // register this component
                Register(this);
        }
    }

You add a Register parameter with an Action<type> value. Here's an example:

    SurveyPrompt sp1 = null;


    void Register1(SurveyPrompt survey)
    {
        sp1 = survey;
        Console.WriteLine("SP1 has title " + sp1.Title);
    }

    protected override void OnInitialized()
    {
        Action<SurveyPrompt> p1 = Register1;

        params1 = new Dictionary<string, object>()
        {
            { "Title", "Survey Title Here" },
            { "Register", p1 }
        };
    }

    IDictionary<string, object> params1;

Related