Freenzy
Freenzy

Reputation: 41

Blazor - Call components dynamically (by string)

Is there an elegant way to call blazor component dynamically by it's name as a string.

Instead of using:

<User />

I want to call it like in a Vue framework:

<component :is="User" />

I found a solution, but it's not very elegant:

@dynamicComponent("App.Pages.User")

@code {

    RenderFragment dynamicComponent(string name) => builder =>
    {
        Type type = Type.GetType(name);
        builder.OpenComponent(0, type);

        builder.CloseComponent();
    };
}

Any ideas?

Upvotes: 2

Views: 1051

Answers (1)

Kyle B
Kyle B

Reputation: 2889

I think there is, for example, imagine we had defined three components,

  1. TabParent.razor
  2. Tab.razor
  3. TabContent.razor

Here is their usage:

<TabParent CurrentTab="@currentTabName">
  <Tab @OnClick="@(() => swapTab("tab1"))">Tab 1</Tab>
  <Tab @OnClick="@(() => swapTab("tab2"))">Tab 2</Tab>

  <TabContent Name="tab1">
    Any other Components here
  </TabContent>

  <TabContent Name="tab2">
    Any other Components here
  </TabContent>
</TabParent>

@code {
  string currentTabName;

  void swapTab(string tabName)
  {
    currentTabName = tabName;
  }
}

Here is the TabParent component:

<div>
  <CascadingValue Name="CurrentTab" Value="@CurrentTab">
    @ChildContent
  </CascadingValue>
</div>

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

  [Parameter]
  public RenderFragment ChildContent { get; set; }
}

And here is the TabChild component:

@if(CurrentTab == TabName) // <-- this way the component won't render unless it is the current tab
{
  <div class="tab-content">
    @ChildContent
  </div>
}

@code {
  [CascadingParameter(Name="CurrentTab")]
  public string CurrentTab { get; set; }

  [Parameter]
  public string TabName { get; set; }

  [Parameter]
  public RenderFragment ChildContent { get; set; }
}

Upvotes: 1

Related Questions