Udostępnij za pośrednictwem


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.

Ostrzeżenie

Ta wersja ASP.NET Core nie jest już obsługiwana. Aby uzyskać więcej informacji, zobacz zasady pomocy technicznej platformy .NET i platformy .NET Core. 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 do componentType 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:

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)

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ć, że this 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.

Dodatkowe zasoby