Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Observação
Esta não é a versão mais recente deste artigo. Para a versão atual, consulte a versão .NET 10 deste artigo.
Advertência
Esta versão do ASP.NET Core não é mais suportada. Para obter mais informações, consulte a Política de suporte do .NET e do .NET Core. Para a versão atual, consulte a versão .NET 9 deste artigo.
Por Dave Brock
Use o componente incorporado DynamicComponent para renderizar os componentes por tipo.
Componentes dinâmicos
A DynamicComponent é útil para renderizar componentes sem iterar entre tipos possíveis ou usar lógica condicional. Por exemplo, DynamicComponent pode renderizar um componente com base numa seleção do utilizador a partir de um menu pendente.
No exemplo a seguir:
-
componentTypeespecifica o tipo. -
parametersespecifica parâmetros do componente para passar aocomponentTypecomponente.
<DynamicComponent Type="componentType" Parameters="parameters" />
@code {
private Type componentType = ...;
private IDictionary<string, object> parameters = ...;
}
Para mais informações sobre a passagem dos valores dos parâmetros, consulte a secção Passagem de parâmetros mais adiante neste artigo.
Example
No exemplo seguinte, um Razor componente renderiza um componente com base na seleção do utilizador a partir de uma lista suspensa de quatro valores possíveis.
| Seleção do porta-aviões espaciais pelo utilizador | Componente partilhado Razor para renderizar |
|---|---|
| Laboratório de Foguetes® | RocketLab.razor |
| SpaceX® | SpaceX.razor |
| ULA® | UnitedLaunchAlliance.razor |
| Virgin Galactic® | VirginGalactic.razor |
RocketLab.razor:
<h2>Rocket Lab®</h2>
<p>
Rocket Lab is a registered trademark of
<a href="https://www.rocketlabusa.com/">Rocket Lab USA Inc.</a>
</p>
SpaceX.razor:
<h2>SpaceX®</h2>
<p>
SpaceX is a registered trademark of
<a href="https://www.spacex.com/">Space Exploration Technologies Corp.</a>
</p>
UnitedLaunchAlliance.razor:
<h2>United Launch Alliance®</h2>
<p>
United Launch Alliance and ULA are registered trademarks of
<a href="https://www.ulalaunch.com/">United Launch Alliance, LLC</a>.
</p>
VirginGalactic.razor:
<h2>Virgin Galactic®</h2>
<p>
Virgin Galactic is a registered trademark of
<a href="https://www.virgingalactic.com/">Galactic Enterprises, LLC</a>.
</p>
DynamicComponent1.razor:
@page "/dynamic-component-1"
<PageTitle>Dynamic Component 1</PageTitle>
<h1>Dynamic Component Example 1</h1>
<p>
<label>
Select your transport:
<select @onchange="OnDropdownChange">
<option value="">Select a value</option>
@foreach (var entry in components.Keys)
{
<option value="@entry">@entry</option>
}
</select>
</label>
</p>
@if (selectedType is not null)
{
<div class="border border-primary my-1 p-1">
<DynamicComponent Type="selectedType" />
</div>
}
@code {
private readonly Dictionary<string, Type> components = new()
{
["Rocket Lab"] = typeof(RocketLab),
["SpaceX"] = typeof(SpaceX),
["ULA"] = typeof(UnitedLaunchAlliance),
["Virgin Galactic"] = typeof(VirginGalactic)
};
private Type? selectedType;
private void OnDropdownChange(ChangeEventArgs e)
{
if ((e.Value is string dropdownValue) &&
!String.IsNullOrWhiteSpace(dropdownValue))
{
selectedType = components[dropdownValue];
}
else
{
selectedType = null;
}
}
}
RocketLab.razor:
<h2>Rocket Lab®</h2>
<p>
Rocket Lab is a registered trademark of
<a href="https://www.rocketlabusa.com/">Rocket Lab USA Inc.</a>
</p>
SpaceX.razor:
<h2>SpaceX®</h2>
<p>
SpaceX is a registered trademark of
<a href="https://www.spacex.com/">Space Exploration Technologies Corp.</a>
</p>
UnitedLaunchAlliance.razor:
<h2>United Launch Alliance®</h2>
<p>
United Launch Alliance and ULA are registered trademarks of
<a href="https://www.ulalaunch.com/">United Launch Alliance, LLC</a>.
</p>
VirginGalactic.razor:
<h2>Virgin Galactic®</h2>
<p>
Virgin Galactic is a registered trademark of
<a href="https://www.virgingalactic.com/">Galactic Enterprises, LLC</a>.
</p>
DynamicComponent1.razor:
@page "/dynamic-component-1"
<PageTitle>Dynamic Component 1</PageTitle>
<h1>Dynamic Component Example 1</h1>
<p>
<label>
Select your transport:
<select @onchange="OnDropdownChange">
<option value="">Select a value</option>
@foreach (var entry in components.Keys)
{
<option value="@entry">@entry</option>
}
</select>
</label>
</p>
@if (selectedType is not null)
{
<div class="border border-primary my-1 p-1">
<DynamicComponent Type="selectedType" />
</div>
}
@code {
private readonly Dictionary<string, Type> components = new()
{
["Rocket Lab"] = typeof(RocketLab),
["SpaceX"] = typeof(SpaceX),
["ULA"] = typeof(UnitedLaunchAlliance),
["Virgin Galactic"] = typeof(VirginGalactic)
};
private Type? selectedType;
private void OnDropdownChange(ChangeEventArgs e)
{
if ((e.Value is string dropdownValue) &&
!String.IsNullOrWhiteSpace(dropdownValue))
{
selectedType = components[dropdownValue];
}
else
{
selectedType = null;
}
}
}
RocketLab.razor:
<h2>Rocket Lab®</h2>
<p>
Rocket Lab is a registered trademark of
<a href="https://www.rocketlabusa.com/">Rocket Lab USA Inc.</a>
</p>
SpaceX.razor:
<h2>SpaceX®</h2>
<p>
SpaceX is a registered trademark of
<a href="https://www.spacex.com/">Space Exploration Technologies Corp.</a>
</p>
UnitedLaunchAlliance.razor:
<h2>United Launch Alliance®</h2>
<p>
United Launch Alliance and ULA are registered trademarks of
<a href="https://www.ulalaunch.com/">United Launch Alliance, LLC</a>.
</p>
VirginGalactic.razor:
<h2>Virgin Galactic®</h2>
<p>
Virgin Galactic is a registered trademark of
<a href="https://www.virgingalactic.com/">Galactic Enterprises, LLC</a>.
</p>
DynamicComponentExample1.razor:
@page "/dynamiccomponent-example-1"
<h1><code>DynamicComponent</code> Component Example 1</h1>
<p>
<label>
Select your transport:
<select @onchange="OnDropdownChange">
<option value="">Select a value</option>
@foreach (var entry in components.Keys)
{
<option value="@entry">@entry</option>
}
</select>
</label>
</p>
@if (selectedType is not null)
{
<div class="border border-primary my-1 p-1">
<DynamicComponent Type="selectedType" />
</div>
}
@code {
private readonly Dictionary<string, Type> components = new()
{
["Rocket Lab"] = typeof(RocketLab),
["SpaceX"] = typeof(SpaceX),
["ULA"] = typeof(UnitedLaunchAlliance),
["Virgin Galactic"] = typeof(VirginGalactic)
};
private Type? selectedType;
private void OnDropdownChange(ChangeEventArgs e)
{
if ((e.Value is string dropdownValue) && !String.IsNullOrWhiteSpace(dropdownValue))
{
selectedType = components[dropdownValue];
}
else
{
selectedType = null;
}
}
}
RocketLab.razor:
<h2>Rocket Lab®</h2>
<p>
Rocket Lab is a registered trademark of
<a href="https://www.rocketlabusa.com/">Rocket Lab USA Inc.</a>
</p>
SpaceX.razor:
<h2>SpaceX®</h2>
<p>
SpaceX is a registered trademark of
<a href="https://www.spacex.com/">Space Exploration Technologies Corp.</a>
</p>
UnitedLaunchAlliance.razor:
<h2>United Launch Alliance®</h2>
<p>
United Launch Alliance and ULA are registered trademarks of
<a href="https://www.ulalaunch.com/">United Launch Alliance, LLC</a>.
</p>
VirginGalactic.razor:
<h2>Virgin Galactic®</h2>
<p>
Virgin Galactic is a registered trademark of
<a href="https://www.virgingalactic.com/">Galactic Enterprises, LLC</a>.
</p>
DynamicComponentExample1.razor:
@page "/dynamiccomponent-example-1"
<h1><code>DynamicComponent</code> Component Example 1</h1>
<p>
<label>
Select your transport:
<select @onchange="OnDropdownChange">
<option value="">Select a value</option>
@foreach (var entry in components.Keys)
{
<option value="@entry">@entry</option>
}
</select>
</label>
</p>
@if (selectedType is not null)
{
<div class="border border-primary my-1 p-1">
<DynamicComponent Type="selectedType" />
</div>
}
@code {
private readonly Dictionary<string, Type> components = new()
{
["Rocket Lab"] = typeof(RocketLab),
["SpaceX"] = typeof(SpaceX),
["ULA"] = typeof(UnitedLaunchAlliance),
["Virgin Galactic"] = typeof(VirginGalactic)
};
private Type? selectedType;
private void OnDropdownChange(ChangeEventArgs e)
{
if ((e.Value is string dropdownValue) && !String.IsNullOrWhiteSpace(dropdownValue))
{
selectedType = components[dropdownValue];
}
else
{
selectedType = null;
}
}
}
No exemplo anterior:
- Um Dictionary<TKey,TValue> é usado para gerir os componentes a serem exibidos.
- Os nomes servem como chaves do dicionário e são fornecidos como opções de seleção.
- Os tipos de componentes são armazenados como valores de dicionário usando o
typeofoperador.
Parâmetros de aprovação
Se os componentes renderizados dinamicamente tiverem parâmetros de componente, passe-os para o DynamicComponent como um IDictionary<string, object>. O string é o nome do parâmetro, e o object é o valor do parâmetro.
O exemplo seguinte configura um objeto de metadados componente (ComponentMetadata) para fornecer valores de parâmetros a componentes renderizados dinamicamente com base no nome do tipo. O exemplo é apenas uma das várias abordagens que pode adotar. Os dados de parâmetros também podem ser fornecidos a partir de uma API web, uma base de dados ou um método. O único requisito é que a abordagem retorne um IDictionary<string, object>.
ComponentMetadata.cs:
namespace BlazorSample;
public class ComponentMetadata
{
public required Type Type { get; init; }
public required string Name { get; init; }
public Dictionary<string, object> Parameters { get; } = [];
}
namespace BlazorSample;
public class ComponentMetadata
{
public required Type Type { get; init; }
public required string Name { get; init; }
public Dictionary<string, object> Parameters { get; } = [];
}
public class ComponentMetadata
{
public required Type Type { get; init; }
public required string Name { get; init; }
public Dictionary<string, object> Parameters { get; } = new();
}
public class ComponentMetadata
{
public Type? Type { get; init; }
public string? Name { get; init; }
public Dictionary<string, object> Parameters { get; } = new();
}
O seguinte RocketLabWithWindowSeat componente (RocketLabWithWindowSeat.razor) foi atualizado a partir do exemplo anterior para incluir um parâmetro de componente nomeado WindowSeat para especificar se o passageiro prefere um lugar na janela no seu voo:
RocketLabWithWindowSeat.razor:
<h2>Rocket Lab®</h2>
<p>
User selected a window seat: @WindowSeat
</p>
<p>
Rocket Lab is a trademark of
<a href="https://www.rocketlabusa.com/">Rocket Lab USA Inc.</a>
</p>
@code {
[Parameter]
public bool WindowSeat { get; set; }
}
<h2>Rocket Lab®</h2>
<p>
User selected a window seat: @WindowSeat
</p>
<p>
Rocket Lab is a trademark of
<a href="https://www.rocketlabusa.com/">Rocket Lab USA Inc.</a>
</p>
@code {
[Parameter]
public bool WindowSeat { get; set; }
}
<h2>Rocket Lab®</h2>
<p>
User selected a window seat: @WindowSeat
</p>
<p>
Rocket Lab is a trademark of
<a href="https://www.rocketlabusa.com/">Rocket Lab USA Inc.</a>
</p>
@code {
[Parameter]
public bool WindowSeat { get; set; }
}
<h2>Rocket Lab®</h2>
<p>
User selected a window seat: @WindowSeat
</p>
<p>
Rocket Lab is a trademark of
<a href="https://www.rocketlabusa.com/">Rocket Lab USA Inc.</a>
</p>
@code {
[Parameter]
public bool WindowSeat { get; set; }
}
No exemplo a seguir:
- Apenas o
RocketLabWithWindowSeatparâmetro do componente para um lugar na janela (WindowSeat) recebe o valor daWindow Seatcaixa de seleção. - Os nomes dos componentes são usados como chaves de dicionário usando o
nameofoperador, que devolve os nomes dos componentes como cadeias constantes. - Os componentes renderizados dinamicamente são componentes partilhados:
- Mostrado nesta secção do artigo:
RocketLabWithWindowSeat(RocketLabWithWindowSeat.razor) - Componentes apresentados na secção de Exemplo anteriormente neste artigo:
-
SpaceX(SpaceX.razor) -
UnitedLaunchAlliance(UnitedLaunchAlliance.razor) -
VirginGalactic(VirginGalactic.razor)
-
- Mostrado nesta secção do artigo:
DynamicComponent2.razor:
@page "/dynamic-component-2"
<PageTitle>Dynamic Component 2</PageTitle>
<h1>Dynamic Component Example 2</h1>
<p>
<label>
<input type="checkbox" @bind="windowSeat"
@bind:after="HandleWindowSeatChanged" />
Window Seat (Rocket Lab only)
</label>
</p>
<p>
<label>
Select your transport:
<select @onchange="OnDropdownChange">
<option value="">Select a value</option>
@foreach (var c in components)
{
<option value="@c.Key">@c.Value.Name</option>
}
</select>
</label>
</p>
@if (selectedComponent is not null)
{
<div class="border border-primary my-1 p-1">
<DynamicComponent Type="selectedComponent.Type"
Parameters="selectedComponent.Parameters" />
</div>
}
@code {
private Dictionary<string, ComponentMetadata> components =
new()
{
[nameof(RocketLabWithWindowSeat)] = new ComponentMetadata()
{
Type = typeof(RocketLabWithWindowSeat),
Name = "Rocket Lab with Window Seat",
Parameters = { [nameof(RocketLabWithWindowSeat.WindowSeat)] = false }
},
[nameof(VirginGalactic)] = new ComponentMetadata()
{
Type = typeof(VirginGalactic),
Name = "Virgin Galactic"
},
[nameof(UnitedLaunchAlliance)] = new ComponentMetadata()
{
Type = typeof(UnitedLaunchAlliance),
Name = "ULA"
},
[nameof(SpaceX)] = new ComponentMetadata()
{
Type = typeof(SpaceX),
Name = "SpaceX"
}
};
private ComponentMetadata? selectedComponent;
private bool windowSeat;
private void HandleWindowSeatChanged()
{
components[nameof(RocketLabWithWindowSeat)]
.Parameters[nameof(RocketLabWithWindowSeat.WindowSeat)] = windowSeat;
}
private void OnDropdownChange(ChangeEventArgs e)
{
if ((e.Value is string dropdownValue) && !String.IsNullOrWhiteSpace(dropdownValue))
{
selectedComponent = components[dropdownValue];
}
else
{
selectedComponent = null;
}
}
}
DynamicComponent2.razor:
@page "/dynamic-component-2"
<PageTitle>Dynamic Component 2</PageTitle>
<h1>Dynamic Component Example 2</h1>
<p>
<label>
<input type="checkbox" @bind="windowSeat"
@bind:after="HandleWindowSeatChanged" />
Window Seat (Rocket Lab only)
</label>
</p>
<p>
<label>
Select your transport:
<select @onchange="OnDropdownChange">
<option value="">Select a value</option>
@foreach (var c in components)
{
<option value="@c.Key">@c.Value.Name</option>
}
</select>
</label>
</p>
@if (selectedComponent is not null)
{
<div class="border border-primary my-1 p-1">
<DynamicComponent Type="selectedComponent.Type"
Parameters="selectedComponent.Parameters" />
</div>
}
@code {
private Dictionary<string, ComponentMetadata> components =
new()
{
[nameof(RocketLabWithWindowSeat)] = new ComponentMetadata()
{
Type = typeof(RocketLabWithWindowSeat),
Name = "Rocket Lab with Window Seat",
Parameters = { [nameof(RocketLabWithWindowSeat.WindowSeat)] = false }
},
[nameof(VirginGalactic)] = new ComponentMetadata()
{
Type = typeof(VirginGalactic),
Name = "Virgin Galactic"
},
[nameof(UnitedLaunchAlliance)] = new ComponentMetadata()
{
Type = typeof(UnitedLaunchAlliance),
Name = "ULA"
},
[nameof(SpaceX)] = new ComponentMetadata()
{
Type = typeof(SpaceX),
Name = "SpaceX"
}
};
private ComponentMetadata? selectedComponent;
private bool windowSeat;
private void HandleWindowSeatChanged()
{
components[nameof(RocketLabWithWindowSeat)]
.Parameters[nameof(RocketLabWithWindowSeat.WindowSeat)] = windowSeat;
}
private void OnDropdownChange(ChangeEventArgs e)
{
if ((e.Value is string dropdownValue) && !String.IsNullOrWhiteSpace(dropdownValue))
{
selectedComponent = components[dropdownValue];
}
else
{
selectedComponent = null;
}
}
}
DynamicComponentExample2.razor:
@page "/dynamiccomponent-example-2"
<h1><code>DynamicComponent</code> Component Example 2</h1>
<p>
<label>
<input type="checkbox" @bind="windowSeat" @bind:after="HandleWindowSeatChanged" />
Window Seat (Rocket Lab only)
</label>
</p>
<p>
<label>
Select your transport:
<select @onchange="OnDropdownChange">
<option value="">Select a value</option>
@foreach (var c in components)
{
<option value="@c.Key">@c.Value.Name</option>
}
</select>
</label>
</p>
@if (selectedComponent is not null)
{
<div class="border border-primary my-1 p-1">
<DynamicComponent Type="selectedComponent.Type"
Parameters="selectedComponent.Parameters" />
</div>
}
@code {
private Dictionary<string, ComponentMetadata> components =
new()
{
[nameof(RocketLabWithWindowSeat)] = new ComponentMetadata()
{
Type = typeof(RocketLabWithWindowSeat),
Name = "Rocket Lab with Window Seat",
Parameters = { [nameof(RocketLabWithWindowSeat.WindowSeat)] = false }
},
[nameof(VirginGalactic)] = new ComponentMetadata()
{
Type = typeof(VirginGalactic),
Name = "Virgin Galactic"
},
[nameof(UnitedLaunchAlliance)] = new ComponentMetadata()
{
Type = typeof(UnitedLaunchAlliance),
Name = "ULA"
},
[nameof(SpaceX)] = new ComponentMetadata()
{
Type = typeof(SpaceX),
Name = "SpaceX"
}
};
private ComponentMetadata? selectedComponent;
private bool windowSeat;
private void HandleWindowSeatChanged()
{
components[nameof(RocketLabWithWindowSeat)]
.Parameters[nameof(RocketLabWithWindowSeat.WindowSeat)] = windowSeat;
}
private void OnDropdownChange(ChangeEventArgs e)
{
if ((e.Value is string dropdownValue) && !String.IsNullOrWhiteSpace(dropdownValue))
{
selectedComponent = components[dropdownValue];
}
else
{
selectedComponent = null;
}
}
}
DynamicComponentExample2.razor:
@page "/dynamiccomponent-example-2"
<h1><code>DynamicComponent</code> Component Example 2</h1>
<p>
<label>
<input type="checkbox" @bind="WindowSeat" />
Window Seat (Rocket Lab only)
</label>
</p>
<p>
<label>
Select your transport:
<select @onchange="OnDropdownChange">
<option value="">Select a value</option>
@foreach (var c in components)
{
<option value="@c.Key">@c.Value.Name</option>
}
</select>
</label>
</p>
@if (selectedComponent is not null)
{
<div class="border border-primary my-1 p-1">
<DynamicComponent Type="selectedComponent.Type"
Parameters="selectedComponent.Parameters" />
</div>
}
@code {
private Dictionary<string, ComponentMetadata> components =
new()
{
[nameof(RocketLabWithWindowSeat)] = new ComponentMetadata()
{
Type = typeof(RocketLabWithWindowSeat),
Name = "Rocket Lab with Window Seat",
Parameters = { [nameof(RocketLabWithWindowSeat.WindowSeat)] = false }
},
[nameof(VirginGalactic)] = new ComponentMetadata()
{
Type = typeof(VirginGalactic),
Name = "Virgin Galactic"
},
[nameof(UnitedLaunchAlliance)] = new ComponentMetadata()
{
Type = typeof(UnitedLaunchAlliance),
Name = "ULA"
},
[nameof(SpaceX)] = new ComponentMetadata()
{
Type = typeof(SpaceX),
Name = "SpaceX"
}
};
private ComponentMetadata? selectedComponent;
private bool windowSeat;
private bool WindowSeat
{
get { return windowSeat; }
set
{
windowSeat = value;
components[nameof(RocketLabWithWindowSeat)]
.Parameters[nameof(RocketLabWithWindowSeat.WindowSeat)] = windowSeat;
}
}
private void OnDropdownChange(ChangeEventArgs e)
{
if ((e.Value is string dropdownValue) && !String.IsNullOrWhiteSpace(dropdownValue))
{
selectedComponent = components[dropdownValue];
}
else
{
selectedComponent = null;
}
}
}
Chamadas de retorno de eventos (EventCallback)
Os callbacks de eventos (EventCallback) podem ser passados para um DynamicComponent no seu dicionário de parâmetros.
ComponentMetadata.cs:
namespace BlazorSample;
public class ComponentMetadata
{
public required Type Type { get; init; }
public required string Name { get; init; }
public Dictionary<string, object> Parameters { get; } = [];
}
namespace BlazorSample;
public class ComponentMetadata
{
public required Type Type { get; init; }
public required string Name { get; init; }
public Dictionary<string, object> Parameters { get; } = [];
}
public class ComponentMetadata
{
public required Type Type { get; init; }
public required string Name { get; init; }
public Dictionary<string, object> Parameters { get; } = new();
}
public class ComponentMetadata
{
public Type? Type { get; init; }
public string? Name { get; init; }
public Dictionary<string, object> Parameters { get; } = new();
}
Implemente um parâmetro de callback de evento (EventCallback) dentro de cada componente renderizado dinamicamente.
RocketLab2.razor:
<h2>Rocket Lab®</h2>
<p>
Rocket Lab is a registered trademark of
<a href="https://www.rocketlabusa.com/">Rocket Lab USA Inc.</a>
</p>
<button @onclick="OnClickCallback">
Trigger a Parent component method
</button>
@code {
[Parameter]
public EventCallback<MouseEventArgs> OnClickCallback { get; set; }
}
<h2>Rocket Lab®</h2>
<p>
Rocket Lab is a registered trademark of
<a href="https://www.rocketlabusa.com/">Rocket Lab USA Inc.</a>
</p>
<button @onclick="OnClickCallback">
Trigger a Parent component method
</button>
@code {
[Parameter]
public EventCallback<MouseEventArgs> OnClickCallback { get; set; }
}
<h2>Rocket Lab®</h2>
<p>
Rocket Lab is a registered trademark of
<a href="https://www.rocketlabusa.com/">Rocket Lab USA Inc.</a>
</p>
<button @onclick="OnClickCallback">
Trigger a Parent component method
</button>
@code {
[Parameter]
public EventCallback<MouseEventArgs> OnClickCallback { get; set; }
}
<h2>Rocket Lab®</h2>
<p>
Rocket Lab is a registered trademark of
<a href="https://www.rocketlabusa.com/">Rocket Lab USA Inc.</a>
</p>
<button @onclick="OnClickCallback">
Trigger a Parent component method
</button>
@code {
[Parameter]
public EventCallback<MouseEventArgs> OnClickCallback { get; set; }
}
SpaceX2.razor:
<h2>SpaceX®</h2>
<p>
SpaceX is a registered trademark of
<a href="https://www.spacex.com/">Space Exploration Technologies Corp.</a>
</p>
<button @onclick="OnClickCallback">
Trigger a Parent component method
</button>
@code {
[Parameter]
public EventCallback<MouseEventArgs> OnClickCallback { get; set; }
}
<h2>SpaceX®</h2>
<p>
SpaceX is a registered trademark of
<a href="https://www.spacex.com/">Space Exploration Technologies Corp.</a>
</p>
<button @onclick="OnClickCallback">
Trigger a Parent component method
</button>
@code {
[Parameter]
public EventCallback<MouseEventArgs> OnClickCallback { get; set; }
}
<h2>SpaceX®</h2>
<p>
SpaceX is a registered trademark of
<a href="https://www.spacex.com/">Space Exploration Technologies Corp.</a>
</p>
<button @onclick="OnClickCallback">
Trigger a Parent component method
</button>
@code {
[Parameter]
public EventCallback<MouseEventArgs> OnClickCallback { get; set; }
}
<h2>SpaceX®</h2>
<p>
SpaceX is a registered trademark of
<a href="https://www.spacex.com/">Space Exploration Technologies Corp.</a>
</p>
<button @onclick="OnClickCallback">
Trigger a Parent component method
</button>
@code {
[Parameter]
public EventCallback<MouseEventArgs> OnClickCallback { get; set; }
}
UnitedLaunchAlliance2.razor:
<h2>United Launch Alliance®</h2>
<p>
United Launch Alliance and ULA are registered trademarks of
<a href="https://www.ulalaunch.com/">United Launch Alliance, LLC</a>.
</p>
<button @onclick="OnClickCallback">
Trigger a Parent component method
</button>
@code {
[Parameter]
public EventCallback<MouseEventArgs> OnClickCallback { get; set; }
}
<h2>United Launch Alliance®</h2>
<p>
United Launch Alliance and ULA are registered trademarks of
<a href="https://www.ulalaunch.com/">United Launch Alliance, LLC</a>.
</p>
<button @onclick="OnClickCallback">
Trigger a Parent component method
</button>
@code {
[Parameter]
public EventCallback<MouseEventArgs> OnClickCallback { get; set; }
}
<h2>United Launch Alliance®</h2>
<p>
United Launch Alliance and ULA are registered trademarks of
<a href="https://www.ulalaunch.com/">United Launch Alliance, LLC</a>.
</p>
<button @onclick="OnClickCallback">
Trigger a Parent component method
</button>
@code {
[Parameter]
public EventCallback<MouseEventArgs> OnClickCallback { get; set; }
}
<h2>United Launch Alliance®</h2>
<p>
United Launch Alliance and ULA are registered trademarks of
<a href="https://www.ulalaunch.com/">United Launch Alliance, LLC</a>.
</p>
<button @onclick="OnClickCallback">
Trigger a Parent component method
</button>
@code {
[Parameter]
public EventCallback<MouseEventArgs> OnClickCallback { get; set; }
}
VirginGalactic2.razor:
<h2>Virgin Galactic®</h2>
<p>
Virgin Galactic is a registered trademark of
<a href="https://www.virgingalactic.com/">Galactic Enterprises, LLC</a>.
</p>
<button @onclick="OnClickCallback">
Trigger a Parent component method
</button>
@code {
[Parameter]
public EventCallback<MouseEventArgs> OnClickCallback { get; set; }
}
<h2>Virgin Galactic®</h2>
<p>
Virgin Galactic is a registered trademark of
<a href="https://www.virgingalactic.com/">Galactic Enterprises, LLC</a>.
</p>
<button @onclick="OnClickCallback">
Trigger a Parent component method
</button>
@code {
[Parameter]
public EventCallback<MouseEventArgs> OnClickCallback { get; set; }
}
<h2>Virgin Galactic®</h2>
<p>
Virgin Galactic is a registered trademark of
<a href="https://www.virgingalactic.com/">Galactic Enterprises, LLC</a>.
</p>
<button @onclick="OnClickCallback">
Trigger a Parent component method
</button>
@code {
[Parameter]
public EventCallback<MouseEventArgs> OnClickCallback { get; set; }
}
<h2>Virgin Galactic®</h2>
<p>
Virgin Galactic is a registered trademark of
<a href="https://www.virgingalactic.com/">Galactic Enterprises, LLC</a>.
</p>
<button @onclick="OnClickCallback">
Trigger a Parent component method
</button>
@code {
[Parameter]
public EventCallback<MouseEventArgs> OnClickCallback { get; set; }
}
No exemplo seguinte do componente pai, o ShowDTMessage método atribui uma string com o tempo atual a message, e o valor de message é renderizado.
O componente pai passa o método de callback, ShowDTMessage no dicionário de parâmetros:
- A
stringchave é o nome do método de retorno,OnClickCallback. - O valor
objecté criado por EventCallbackFactory.Create para o método de retorno principal,ShowDTMessage. Note que athispalavra-chave não é suportada na inicialização de campos C#, pelo que uma propriedade C# é usada para o dicionário de parâmetros.
DynamicComponent3.razor:
@page "/dynamic-component-3"
<PageTitle>Dynamic Component 3</PageTitle>
<h1>Dynamic Component Example 3</h1>
<p>
<label>
Select your transport:
<select @onchange="OnDropdownChange">
<option value="">Select a value</option>
@foreach (var c in Components)
{
<option value="@c.Key">@c.Value.Name</option>
}
</select>
</label>
</p>
@if (selectedComponent is not null)
{
<div class="border border-primary my-1 p-1">
<DynamicComponent Type="selectedComponent.Type"
Parameters="selectedComponent.Parameters" />
</div>
}
<p>
@message
</p>
@code {
private ComponentMetadata? selectedComponent;
private string? message;
private Dictionary<string, ComponentMetadata> Components =>
new()
{
[nameof(RocketLab2)] = new ComponentMetadata()
{
Type = typeof(RocketLab2),
Name = "Rocket Lab",
Parameters = { [nameof(RocketLab2.OnClickCallback)] =
EventCallback.Factory.Create<MouseEventArgs>(this, ShowDTMessage) }
},
[nameof(VirginGalactic2)] = new ComponentMetadata()
{
Type = typeof(VirginGalactic2),
Name = "Virgin Galactic",
Parameters = { [nameof(VirginGalactic2.OnClickCallback)] =
EventCallback.Factory.Create<MouseEventArgs>(this, ShowDTMessage) }
},
[nameof(UnitedLaunchAlliance2)] = new ComponentMetadata()
{
Type = typeof(UnitedLaunchAlliance2),
Name = "ULA",
Parameters = { [nameof(UnitedLaunchAlliance2.OnClickCallback)] =
EventCallback.Factory.Create<MouseEventArgs>(this, ShowDTMessage) }
},
[nameof(SpaceX2)] = new ComponentMetadata()
{
Type = typeof(SpaceX2),
Name = "SpaceX",
Parameters = { [nameof(SpaceX2.OnClickCallback)] =
EventCallback.Factory.Create<MouseEventArgs>(this, ShowDTMessage) }
}
};
private void OnDropdownChange(ChangeEventArgs e)
{
if ((e.Value is string dropdownValue) && !String.IsNullOrWhiteSpace(dropdownValue))
{
selectedComponent = Components[dropdownValue];
}
else
{
selectedComponent = null;
}
}
private void ShowDTMessage(MouseEventArgs e) =>
message = $"The current DT is: {DateTime.Now}.";
}
DynamicComponent3.razor:
@page "/dynamic-component-3"
<PageTitle>Dynamic Component 3</PageTitle>
<h1>Dynamic Component Example 3</h1>
<p>
<label>
Select your transport:
<select @onchange="OnDropdownChange">
<option value="">Select a value</option>
@foreach (var c in Components)
{
<option value="@c.Key">@c.Value.Name</option>
}
</select>
</label>
</p>
@if (selectedComponent is not null)
{
<div class="border border-primary my-1 p-1">
<DynamicComponent Type="selectedComponent.Type"
Parameters="selectedComponent.Parameters" />
</div>
}
<p>
@message
</p>
@code {
private ComponentMetadata? selectedComponent;
private string? message;
private Dictionary<string, ComponentMetadata> Components =>
new()
{
[nameof(RocketLab2)] = new ComponentMetadata()
{
Type = typeof(RocketLab2),
Name = "Rocket Lab",
Parameters = { [nameof(RocketLab2.OnClickCallback)] =
EventCallback.Factory.Create<MouseEventArgs>(this, ShowDTMessage) }
},
[nameof(VirginGalactic2)] = new ComponentMetadata()
{
Type = typeof(VirginGalactic2),
Name = "Virgin Galactic",
Parameters = { [nameof(VirginGalactic2.OnClickCallback)] =
EventCallback.Factory.Create<MouseEventArgs>(this, ShowDTMessage) }
},
[nameof(UnitedLaunchAlliance2)] = new ComponentMetadata()
{
Type = typeof(UnitedLaunchAlliance2),
Name = "ULA",
Parameters = { [nameof(UnitedLaunchAlliance2.OnClickCallback)] =
EventCallback.Factory.Create<MouseEventArgs>(this, ShowDTMessage) }
},
[nameof(SpaceX2)] = new ComponentMetadata()
{
Type = typeof(SpaceX2),
Name = "SpaceX",
Parameters = { [nameof(SpaceX2.OnClickCallback)] =
EventCallback.Factory.Create<MouseEventArgs>(this, ShowDTMessage) }
}
};
private void OnDropdownChange(ChangeEventArgs e)
{
if ((e.Value is string dropdownValue) && !String.IsNullOrWhiteSpace(dropdownValue))
{
selectedComponent = Components[dropdownValue];
}
else
{
selectedComponent = null;
}
}
private void ShowDTMessage(MouseEventArgs e) =>
message = $"The current DT is: {DateTime.Now}.";
}
DynamicComponentExample3.razor:
@page "/dynamiccomponent-example-3"
<h1><code>DynamicComponent</code> Component Example 3</h1>
<p>
<label>
Select your transport:
<select @onchange="OnDropdownChange">
<option value="">Select a value</option>
@foreach (var c in Components)
{
<option value="@c.Key">@c.Value.Name</option>
}
</select>
</label>
</p>
@if (selectedComponent is not null)
{
<div class="border border-primary my-1 p-1">
<DynamicComponent Type="selectedComponent.Type"
Parameters="selectedComponent.Parameters" />
</div>
}
<p>
@message
</p>
@code {
private ComponentMetadata? selectedComponent;
private string? message;
private Dictionary<string, ComponentMetadata> Components =>
new()
{
[nameof(RocketLab2)] = new ComponentMetadata()
{
Type = typeof(RocketLab2),
Name = "Rocket Lab",
Parameters = { [nameof(RocketLab2.OnClickCallback)] =
EventCallback.Factory.Create<MouseEventArgs>(this, ShowDTMessage) }
},
[nameof(VirginGalactic2)] = new ComponentMetadata()
{
Type = typeof(VirginGalactic2),
Name = "Virgin Galactic",
Parameters = { [nameof(VirginGalactic2.OnClickCallback)] =
EventCallback.Factory.Create<MouseEventArgs>(this, ShowDTMessage) }
},
[nameof(UnitedLaunchAlliance2)] = new ComponentMetadata()
{
Type = typeof(UnitedLaunchAlliance2),
Name = "ULA",
Parameters = { [nameof(UnitedLaunchAlliance2.OnClickCallback)] =
EventCallback.Factory.Create<MouseEventArgs>(this, ShowDTMessage) }
},
[nameof(SpaceX2)] = new ComponentMetadata()
{
Type = typeof(SpaceX2),
Name = "SpaceX",
Parameters = { [nameof(SpaceX2.OnClickCallback)] =
EventCallback.Factory.Create<MouseEventArgs>(this, ShowDTMessage) }
}
};
private void OnDropdownChange(ChangeEventArgs e)
{
if ((e.Value is string dropdownValue) && !String.IsNullOrWhiteSpace(dropdownValue))
{
selectedComponent = Components[dropdownValue];
}
else
{
selectedComponent = null;
}
}
private void ShowDTMessage(MouseEventArgs e) =>
message = $"The current DT is: {DateTime.Now}.";
}
DynamicComponentExample3.razor:
@page "/dynamiccomponent-example-3"
<h1><code>DynamicComponent</code> Component Example 3</h1>
<p>
<label>
Select your transport:
<select @onchange="OnDropdownChange">
<option value="">Select a value</option>
@foreach (var c in Components)
{
<option value="@c.Key">@c.Value.Name</option>
}
</select>
</label>
</p>
@if (selectedComponent is not null)
{
<div class="border border-primary my-1 p-1">
<DynamicComponent Type="selectedComponent.Type"
Parameters="selectedComponent.Parameters" />
</div>
}
<p>
@message
</p>
@code {
private ComponentMetadata? selectedComponent;
private string? message;
private Dictionary<string, ComponentMetadata> Components =>
new()
{
[nameof(RocketLab2)] = new ComponentMetadata()
{
Type = typeof(RocketLab2),
Name = "Rocket Lab",
Parameters = { [nameof(RocketLab2.OnClickCallback)] =
EventCallback.Factory.Create<MouseEventArgs>(this, ShowDTMessage) }
},
[nameof(VirginGalactic2)] = new ComponentMetadata()
{
Type = typeof(VirginGalactic2),
Name = "Virgin Galactic",
Parameters = { [nameof(VirginGalactic2.OnClickCallback)] =
EventCallback.Factory.Create<MouseEventArgs>(this, ShowDTMessage) }
},
[nameof(UnitedLaunchAlliance2)] = new ComponentMetadata()
{
Type = typeof(UnitedLaunchAlliance2),
Name = "ULA",
Parameters = { [nameof(UnitedLaunchAlliance2.OnClickCallback)] =
EventCallback.Factory.Create<MouseEventArgs>(this, ShowDTMessage) }
},
[nameof(SpaceX2)] = new ComponentMetadata()
{
Type = typeof(SpaceX2),
Name = "SpaceX",
Parameters = { [nameof(SpaceX2.OnClickCallback)] =
EventCallback.Factory.Create<MouseEventArgs>(this, ShowDTMessage) }
}
};
private void OnDropdownChange(ChangeEventArgs e)
{
if ((e.Value is string dropdownValue) && !String.IsNullOrWhiteSpace(dropdownValue))
{
selectedComponent = Components[dropdownValue];
}
else
{
selectedComponent = null;
}
}
private void ShowDTMessage(MouseEventArgs e) =>
message = $"The current DT is: {DateTime.Now}.";
}
Evite parâmetros genéricos
Evite o uso de parâmetros genéricos. Se forem usados parâmetros genéricos, cada parâmetro explícito em DynamicComponent efetivamente é uma palavra reservada que não se pode passar a um filho dinâmico. Qualquer novo parâmetro a DynamicComponent que sejam passados é uma alteração quebrada, pois começam a fazer sombra de parâmetros de componente filho que, por acaso, têm o mesmo nome. É improvável que o chamador saiba sempre um conjunto fixo de nomes de parâmetros para passar a todos os possíveis filhos dinâmicos.
Aceda à instância de componente criada dinamicamente
Use a Instance propriedade para aceder à instância de componente criada dinamicamente.
Crie uma interface para descrever a instância de componente criada dinamicamente com quaisquer métodos e propriedades que precise de aceder a partir do componente pai quando este for carregado dinamicamente. O exemplo seguinte especifica um Log método para implementação em componentes.
Interfaces/ILoggable.cs:
using Microsoft.AspNetCore.Components;
namespace BlazorSample.Interfaces;
public interface ILoggable : IComponent
{
public void Log();
}
using Microsoft.AspNetCore.Components;
namespace BlazorSample.Interfaces;
public interface ILoggable : IComponent
{
public void Log();
}
using Microsoft.AspNetCore.Components;
namespace BlazorSample.Interfaces;
public interface ILoggable : IComponent
{
public void Log();
}
using Microsoft.AspNetCore.Components;
namespace BlazorSample.Interfaces;
public interface ILoggable : IComponent
{
public void Log();
}
Cada definição de componente implementa a interface. O exemplo seguinte é um componente modificado do Rocket Lab® da secção de Exemplo que regista uma cadeia através do seu Log método.
RocketLab3.razor:
@using BlazorSample.Interfaces
@implements ILoggable
@inject ILogger<RocketLab3> Logger
<h2>Rocket Lab®</h2>
<p>
Rocket Lab is a registered trademark of
<a href="https://www.rocketlabusa.com/">Rocket Lab USA Inc.</a>
</p>
@code {
public void Log() => Logger.LogInformation("Woot! I logged this call!");
}
@using BlazorSample.Interfaces
@implements ILoggable
@inject ILogger<RocketLab3> Logger
<h2>Rocket Lab®</h2>
<p>
Rocket Lab is a registered trademark of
<a href="https://www.rocketlabusa.com/">Rocket Lab USA Inc.</a>
</p>
@code {
public void Log() => Logger.LogInformation("Woot! I logged this call!");
}
@using BlazorSample.Interfaces
@implements ILoggable
@inject ILogger<RocketLab3> Logger
<h2>Rocket Lab®</h2>
<p>
Rocket Lab is a registered trademark of
<a href="https://www.rocketlabusa.com/">Rocket Lab USA Inc.</a>
</p>
@code {
public void Log()
{
Logger.LogInformation("Woot! I logged this call!");
}
}
@using BlazorSample.Interfaces
@implements ILoggable
@inject ILogger<RocketLab3> Logger
<h2>Rocket Lab®</h2>
<p>
Rocket Lab is a registered trademark of
<a href="https://www.rocketlabusa.com/">Rocket Lab USA Inc.</a>
</p>
@code {
public void Log()
{
Logger.LogInformation("Woot! I logged this call!");
}
}
Os restantes três componentes partilhados (VirginGalactic3, UnitedLaunchAlliance3, SpaceX3) recebem tratamento semelhante:
As seguintes diretivas são adicionadas aos componentes, onde o
{COMPONENT TYPE}marcador é o tipo de componente:@using BlazorSample.Interfaces @implements ILoggable @inject ILogger<{COMPONENT TYPE}> LoggerCada componente implementa um
Logmétodo. A categoria de registo escrita pelo logger inclui o nome totalmente qualificado do tipo de componente quando LogInformation é chamada:@code { public void Log() { Logger.LogInformation("Woot! I logged this call!"); } }
O componente pai lança a instância do componente carregado dinamicamente como um ILoggable para aceder aos membros da interface. No exemplo seguinte, quando um botão é selecionado na interface, o método do componente carregado Log é chamado:
...
@using BlazorSample.Interfaces
...
<DynamicComponent Type="..." @ref="dc" />
...
<button @onclick="LogFromLoadedComponent">Log from loaded component</button>
@code {
private DynamicComponent? dc;
...
private void LogFromLoadedComponent() => (dc?.Instance as ILoggable)?.Log();
}
Para uma demonstração funcional do exemplo anterior, veja o DynamicComponent4 componente na Blazor aplicação de exemplo.
Para uma demonstração funcional do exemplo anterior, veja o DynamicComponent4 componente na Blazor aplicação de exemplo.
Para uma demonstração funcional do exemplo anterior, veja o DynamicComponentExample4 componente na Blazor aplicação de exemplo.
Para uma demonstração funcional do exemplo anterior, veja o DynamicComponentExample4 componente na Blazor aplicação de exemplo.
Marcas Comerciais
Rocket Lab é uma marca registada da Rocket Lab USA Inc. A SpaceX é uma marca registada da Space Exploration Technologies Corp. United Launch Alliance e ULA são marcas registadas da United Launch Alliance, LLC. Virgin Galactic é uma marca registada da Galactic Enterprises, LLC.