Dynamiczne renderowanie składników ASP.NET Core Razor
Uwaga
Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z bieżącą wersją, zobacz wersję tego artykułu platformy .NET 9.
Ważne
Te informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany, zanim zostanie wydany komercyjnie. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.
Aby zapoznać się z bieżącą wersją, zobacz wersję tego artykułu platformy .NET 9.
Autor: Dave Brock
Użyj wbudowanego DynamicComponent składnika do renderowania składników według typu.
Składniki dynamiczne
Element jest DynamicComponent przydatny do renderowania składników bez iterowania za pośrednictwem możliwych typów lub używania logiki warunkowej. Na przykład DynamicComponent może renderować składnik na podstawie wyboru użytkownika z listy rozwijanej.
W poniższym przykładzie:
componentType
określa typ.parameters
określa parametry składnika, które mają być przekazywane docomponentType
składnika.
<DynamicComponent Type="componentType" Parameters="parameters" />
@code {
private Type componentType = ...;
private IDictionary<string, object> parameters = ...;
}
Aby uzyskać więcej informacji na temat przekazywania wartości parametrów, zobacz sekcję Przekazywanie parametrów w dalszej części tego artykułu.
Przykład
W poniższym przykładzie Razor składnik renderuje składnik na podstawie wyboru użytkownika z listy rozwijanej czterech możliwych wartości.
Wybór operatora spaceflight użytkownika | Składnik udostępniony Razor do renderowania |
---|---|
Laboratorium® rakietowe | RocketLab.razor |
SpaceX® | SpaceX.razor |
ULA® | UnitedLaunchAlliance.razor |
Dziewica Galaktyka® | 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;
}
}
}
W powyższym przykładzie:
- Element Dictionary<TKey,TValue> służy do zarządzania składnikami do wyświetlania.
- Nazwy służą jako klucze słownika i są udostępniane jako opcje wyboru.
- Typy składników są przechowywane jako wartości słownika
typeof
przy użyciu operatora .
Przekazywanie parametrów
Jeśli składniki renderowane dynamicznie mają parametry składnika, przekaż je do DynamicComponent elementu jako IDictionary<string, object>
. Jest string
to nazwa parametru, a object
parametr jest wartością parametru.
Poniższy przykład umożliwia skonfigurowanie obiektu metadanych składnika (ComponentMetadata
) w celu dostarczania wartości parametrów do składników renderowanych dynamicznie na podstawie nazwy typu. Przykład to tylko jedno z kilku podejść, które można zastosować. Dane parametrów można również dostarczyć z internetowego interfejsu API, bazy danych lub metody. Jedynym wymaganiem jest to, że metoda zwraca IDictionary<string, object>
wartość .
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();
}
Poniższy RocketLabWithWindowSeat
składnik (RocketLabWithWindowSeat.razor
) został zaktualizowany z poprzedniego przykładu w celu uwzględnienia parametru składnika o nazwie WindowSeat
w celu określenia, czy pasażer preferuje miejsce w locie:
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; }
}
W poniższym przykładzie:
RocketLabWithWindowSeat
Tylko parametr składnika dla siedzenia okna (WindowSeat
) otrzymuje wartośćWindow Seat
pola wyboru.- Nazwy składników są używane jako klucze słownika
nameof
przy użyciu operatora, który zwraca nazwy składników jako ciągi stałe. - Składniki renderowane dynamicznie są składnikami udostępnionymi:
- Pokazano w tej sekcji artykułu:
RocketLabWithWindowSeat
(RocketLabWithWindowSeat.razor
) - Składniki pokazane w sekcji Przykład we wcześniejszej części tego artykułu:
SpaceX
(SpaceX.razor
)UnitedLaunchAlliance
(UnitedLaunchAlliance.razor
)VirginGalactic
(VirginGalactic.razor
)
- Pokazano w tej sekcji artykułu:
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;
}
}
}
Wywołania zwrotne zdarzeń (EventCallback
)
Wywołania zwrotne zdarzeń (EventCallback) można przekazać do DynamicComponent elementu w słowniku parametrów.
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();
}
Zaimplementuj parametr wywołania zwrotnego zdarzeń (EventCallback) w każdym składniku renderowany dynamicznie.
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; }
}
W poniższym przykładzie ShowDTMessage
składnika nadrzędnego metoda przypisuje ciąg z bieżącym czasem do message
, a wartość message
jest renderowana.
Składnik nadrzędny przekazuje metodę ShowDTMessage
wywołania zwrotnego w słowniku parametrów:
- Kluczem
string
jest nazwa metody wywołania zwrotnego,OnClickCallback
. - Wartość jest tworzona
object
przez EventCallbackFactory.Create dla metody wywołania zwrotnego nadrzędnego,ShowDTMessage
. Należy pamiętać, żethis
słowo kluczowe nie jest obsługiwane w inicjowaniu pól języka C#, dlatego dla słownika parametrów jest używana właściwość języka C#.
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}.";
}
Unikanie parametrów catch-all
Unikaj używania parametrów catch-all. Jeśli są używane parametry catch-all, każdy jawny parametr DynamicComponent na efektywnie jest zastrzeżonym słowem, którego nie można przekazać do dynamicznego elementu podrzędnego. Wszystkie nowe przekazane DynamicComponent parametry są zmianą powodującą niezgodność, ponieważ zaczynają w tle parametry składnika podrzędnego, które mają taką samą nazwę. Jest mało prawdopodobne, że obiekt wywołujący zawsze wie stały zestaw nazw parametrów do przekazania do wszystkich możliwych elementów podrzędnych dynamicznych.
Uzyskiwanie dostępu do dynamicznie utworzonego wystąpienia składnika
Użyj właściwości , Instance aby uzyskać dostęp do dynamicznie utworzonego wystąpienia składnika.
Utwórz interfejs opisujący dynamicznie utworzone wystąpienie składnika przy użyciu dowolnych metod i właściwości, do których należy uzyskać dostęp ze składnika nadrzędnego, gdy składnik jest ładowany dynamicznie. W poniższym przykładzie określono metodę Log
implementacji składników.
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();
}
Każda definicja składnika implementuje interfejs. Poniższy przykład jest zmodyfikowanym składnikiem Rocket Lab® z sekcji Przykład , która rejestruje ciąg za pośrednictwem jego Log
metody.
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!");
}
}
Pozostałe trzy udostępnione składniki (VirginGalactic3
, UnitedLaunchAlliance3
, SpaceX3
) otrzymują podobne leczenie:
Następujące dyrektywy są dodawane do składników, gdzie
{COMPONENT TYPE}
symbol zastępczy jest typem składnika:@using BlazorSample.Interfaces @implements ILoggable @inject ILogger<{COMPONENT TYPE}> Logger
Każdy składnik implementuje metodę
Log
. Kategoria dziennika napisana przez rejestrator zawiera w pełni kwalifikowaną nazwę typu składnika, gdy LogInformation jest wywoływana:@code { public void Log() { Logger.LogInformation("Woot! I logged this call!"); } }
Składnik nadrzędny rzutuje dynamicznie załadowane wystąpienie składnika jako element ILoggable
umożliwiający dostęp do elementów członkowskich interfejsu. W poniższym przykładzie metoda załadowanego składnika jest wywoływana Log
po wybraniu przycisku w interfejsie użytkownika:
...
@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();
}
Aby zapoznać się z roboczym pokazem poprzedniego przykładu, zobacz DynamicComponent4
składnik w przykładowej Blazor aplikacji.
Aby zapoznać się z roboczym pokazem poprzedniego przykładu, zobacz DynamicComponent4
składnik w przykładowej Blazor aplikacji.
Aby zapoznać się z roboczym pokazem poprzedniego przykładu, zobacz DynamicComponentExample4
składnik w przykładowej Blazor aplikacji.
Aby zapoznać się z roboczym pokazem poprzedniego przykładu, zobacz DynamicComponentExample4
składnik w przykładowej Blazor aplikacji.
Znaki towarowe
Rocket Lab jest zastrzeżonym znakiem towarowym Rocket Lab USA Inc. SpaceX jest zastrzeżonym znakiem towarowym Space Exploration Technologies Corp. United Launch Alliance i ULA są zastrzeżonymi znakami towarowymi United Launch Alliance, LLC. Virgin Galactic jest zastrzeżonym znakiem towarowym Firmy Galactic Enterprises, LLC.