Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Varning
Den här versionen av ASP.NET Core stöds inte längre. Mer information finns i .NET och .NET Core Support Policy. För den aktuella versionen, se .NET 9-versionen av den här artikeln .
Viktig
Den här informationen gäller en förhandsversionsprodukt som kan ändras avsevärt innan den släpps kommersiellt. Microsoft lämnar inga garantier, uttryckliga eller underförstådda, med avseende på den information som tillhandahålls här.
För den aktuella versionen, se .NET 9-versionen av den här artikeln .
Den här artikeln beskriver hur du flödar data från en överordnad Razor komponent till underordnade komponenter.
sammanhängande värden och parametrar ger ett bekvämt sätt att flöda data ned i en komponenthierarki från en överordnad komponent till valfritt antal underordnade komponenter. Till skillnad från komponentparametrarkräver sammanhängande värden och parametrar inte någon attributtilldelning för varje underordnad komponent där data används. Sammanhängande värden och parametrar gör det också möjligt för komponenter att samordna med varandra i en komponenthierarki.
Obs
Kodexemplen i den här artikeln använder nullbara referenstyper (NRT) och .NET-kompilatorn null-state static analysis, som stöds i ASP.NET Core i .NET 6 eller senare. När du riktar in dig på .NET 5 eller tidigare tar du bort null-typbeteckningen (?) från typerna CascadingType?, @ActiveTab?, RenderFragment?, ITab?och TabSet?string? i artikelns exempel.
Sammanhängande värden på rotnivå
Sammanhängande värden på rotnivå kan registreras för hela komponenthierarkin. Namngivna sammanhängande värden och prenumerationer för uppdateringsmeddelanden stöds.
Följande klass används i det här avsnittets exempel.
              Dalek.cs:
// "Dalek" ©Terry Nation https://www.imdb.com/name/nm0622334/
// "Doctor Who" ©BBC https://www.bbc.co.uk/programmes/b006q2x0
namespace BlazorSample;
public class Dalek
{
    public int Units { get; set; }
}
// "Dalek" ©Terry Nation https://www.imdb.com/name/nm0622334/
// "Doctor Who" ©BBC https://www.bbc.co.uk/programmes/b006q2x0
namespace BlazorSample;
public class Dalek
{
    public int Units { get; set; }
}
Följande registreringar görs i appens Program-fil med AddCascadingValue:
- 
              Dalekmed ett egenskapsvärde förUnitsregistreras som ett fast sammanhängande värde.
- En andra Dalekregistrering med ett annat egenskapsvärde förUnitsheter "AlphaGroup".
builder.Services.AddCascadingValue(sp => new Dalek { Units = 123 });
builder.Services.AddCascadingValue("AlphaGroup", sp => new Dalek { Units = 456 });
Följande Daleks komponent visar de överlappande värdena.
              Daleks.razor:
@page "/daleks"
<PageTitle>Daleks</PageTitle>
<h1>Root-level Cascading Value Example</h1>
<ul>
    <li>Dalek Units: @Dalek?.Units</li>
    <li>Alpha Group Dalek Units: @AlphaGroupDalek?.Units</li>
</ul>
<p>
    Dalek© <a href="https://www.imdb.com/name/nm0622334/">Terry Nation</a><br>
    Doctor Who© <a href="https://www.bbc.co.uk/programmes/b006q2x0">BBC</a>
</p>
@code {
    [CascadingParameter]
    public Dalek? Dalek { get; set; }
    [CascadingParameter(Name = "AlphaGroup")]
    public Dalek? AlphaGroupDalek { get; set; }
}
@page "/daleks"
<PageTitle>Daleks</PageTitle>
<h1>Root-level Cascading Value Example</h1>
<ul>
    <li>Dalek Units: @Dalek?.Units</li>
    <li>Alpha Group Dalek Units: @AlphaGroupDalek?.Units</li>
</ul>
<p>
    Dalek© <a href="https://www.imdb.com/name/nm0622334/">Terry Nation</a><br>
    Doctor Who© <a href="https://www.bbc.co.uk/programmes/b006q2x0">BBC</a>
</p>
@code {
    [CascadingParameter]
    public Dalek? Dalek { get; set; }
    [CascadingParameter(Name = "AlphaGroup")]
    public Dalek? AlphaGroupDalek { get; set; }
}
I följande exempel registreras Dalek som ett sammanhängande värde med hjälp av CascadingValueSource<T>, där <T> är typen. Flaggan isFixed anger om värdet är fast. Om falseprenumererar alla mottagare på uppdateringsmeddelanden. Prenumerationer skapar omkostnader och minskar prestanda, så ställ in isFixed på true om värdet inte ändras.
builder.Services.AddCascadingValue(sp =>
{
    var dalek = new Dalek { Units = 789 };
    var source = new CascadingValueSource<Dalek>(dalek, isFixed: false);
    return source;
});
Varning
Registrering av en komponenttyp som ett sammanhängande värde på rotnivå registrerar inte ytterligare tjänster för typen eller tillåter tjänstaktivering i komponenten.
Behandla nödvändiga tjänster separat från kaskadvärden och registrera dem separat från kaskadtypen.
Undvik att använda AddCascadingValue för att registrera en komponenttyp som ett sammanhängande värde. Omslut i stället <Router>...</Router> i komponenten Routes (Components/Routes.razor) med komponenten och implementera global interaktiv återgivning på serversidan (interaktiv SSR). Ett exempel finns i avsnittet CascadingValue komponent.
Kaskaderande värden på rotnivå med meddelanden
Att anropa NotifyChangedAsync för att utfärda uppdateringsmeddelanden kan användas för att signalera flera Razor komponentprenumeranter att ett sammanhängande värde har ändrats. Meddelanden är inte möjliga för prenumeranter som använder statisk återgivning på serversidan (statisk SSR), så prenumeranter måste använda ett interaktivt återgivningsläge.
I följande exempel:
- 
              NotifyingDalekimplementerar INotifyPropertyChanged för att meddela klienter att ett egenskapsvärde har ändrats. När egenskapenUnitshar angetts PropertyChangedEventHandler anropas (PropertyChanged).
- Metoden SetUnitsToOneThousandAsynckan utlösas av prenumeranter för att sättaUnitstill 1 000 med en simulerad fördröjning i bearbetningen.
Tänk på att alla ändringar i tillståndet (eventuella ändringar av egenskapsvärden för klassen) gör att alla komponenter som prenumererar på tillståndet rendreras om, oavsett vilken del av tillståndet de använder. Vi rekommenderar att du skapar detaljerade klasser och samlar dem separat med specifika prenumerationer för att säkerställa att endast komponenter som prenumererar på en viss del av programtillståndet påverkas av ändringar.
Obs
För en Blazor Web App lösning som består av server- och klientprojekt (.Client) placeras följande NotifyingDalek.cs fil i .Client projektet.
              NotifyingDalek.cs:
using System.ComponentModel;
using System.Runtime.CompilerServices;
public class NotifyingDalek : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler? PropertyChanged;
    private int units;
    public int Units
    {
        get => units;
        set
        {
            if (units != value)
            {
                units = value;
                OnPropertyChanged();
            }
        }
    }
    protected virtual void OnPropertyChanged(
        [CallerMemberName] string? propertyName = default)
            => PropertyChanged?.Invoke(this, new(propertyName));
    public async Task SetUnitsToOneThousandAsync()
    {
        // Simulate a three second delay in processing
        await Task.Delay(3000);
        Units = 1000;
    }
}
Följande CascadingStateServiceCollectionExtensions skapar en CascadingValueSource<TValue> från en typ som implementerar INotifyPropertyChanged.
Obs
För en Blazor Web App lösning som består av server- och klientprojekt (.Client) placeras följande CascadingStateServiceCollectionExtensions.cs fil i .Client projektet.
              CascadingStateServiceCollectionExtensions.cs:
using System.ComponentModel;
using Microsoft.AspNetCore.Components;
namespace Microsoft.Extensions.DependencyInjection;
public static class CascadingStateServiceCollectionExtensions
{
    public static IServiceCollection AddNotifyingCascadingValue<T>(
        this IServiceCollection services, T state, bool isFixed = false)
        where T : INotifyPropertyChanged
    {
        return services.AddCascadingValue<T>(sp =>
        {
            return new CascadingStateValueSource<T>(state, isFixed);
        });
    }
    private sealed class CascadingStateValueSource<T>
        : CascadingValueSource<T>, IDisposable where T : INotifyPropertyChanged
    {
        private readonly T state;
        private readonly CascadingValueSource<T> source;
        public CascadingStateValueSource(T state, bool isFixed = false)
            : base(state, isFixed = false)
        {
            this.state = state;
            source = new CascadingValueSource<T>(state, isFixed);
            this.state.PropertyChanged += HandlePropertyChanged;
        }
        private void HandlePropertyChanged(object? sender, PropertyChangedEventArgs e)
        {
            _ = NotifyChangedAsync();
        }
        public void Dispose()
        {
            state.PropertyChanged -= HandlePropertyChanged;
        }
    }
}
Typens PropertyChangedEventHandler (HandlePropertyChanged) anropar CascadingValueSource<TValue>s NotifyChangedAsyncmetod för att meddela prenumeranter att det sammanhängande värdet har ändrats. 
              Task Ignoreras när du anropar NotifyChangedAsync eftersom anropet endast representerar sändningstiden till den synkrona kontexten. Undantag hanteras internt genom att de skickas till renderaren inom ramen för den komponent som kastades när uppdateringen mottogs. Det här är samma sätt som undantag hanteras med en CascadingValue<TValue>, som inte blir informerad om undantag som inträffar inuti meddelandemottagare. Händelsehanteraren kopplas från i Dispose metoden för att förhindra en minnesläcka.
I filen Program skickas NotifyingDalek för att skapa en CascadingValueSource<TValue> med ett initialt Unit-värde på 888 enheter:
builder.Services.AddNotifyingCascadingValue(new NotifyingDalek() { Units = 888 });
Obs
För en Blazor Web App lösning som består av server- och klientprojekt (.Client) placeras föregående kod i varje projekts Program fil.
Följande komponent används för att demonstrera hur förändringen av värdet NotifyingDalek.Units meddelar prenumeranter.
              Daleks.razor:
<h2>Daleks component</h2>
<div>
    <b>Dalek Units:</b> @Dalek?.Units
</div>
<div>
    <label>
        <span style="font-weight:bold">New Unit Count:</span>
        <input @bind="dalekCount" />
    </label>
    <button @onclick="Update">Update</button>
</div>
<div>
    <button @onclick="SetOneThousandUnits">Set Units to 1,000</button>
</div>
<p>
    Dalek© <a href="https://www.imdb.com/name/nm0622334/">Terry Nation</a><br>
    Doctor Who© <a href="https://www.bbc.co.uk/programmes/b006q2x0">BBC</a>
</p>
@code {
    private int dalekCount;
    [CascadingParameter]
    public NotifyingDalek? Dalek { get; set; }
    private void Update()
    {
        if (Dalek is not null)
        {
            Dalek.Units = dalekCount;
            dalekCount = 0;
        }
    }
    private async Task SetOneThousandUnits()
    {
        if (Dalek is not null)
        {
            await Dalek.SetUnitsToOneThousandAsync();
        }
    }
}
För att demonstrera flera prenumerantmeddelanden renderar följande DaleksMain komponent tre Daleks komponenter. När enhetsantalet (Units) för en Dalek komponent uppdateras uppdateras de andra två Dalek komponentprenumeranterna.
              DaleksMain.razor:
@page "/daleks-main"
<PageTitle>Daleks Main</PageTitle>
<h1>Daleks Main</h1>
<Daleks />
<Daleks />
<Daleks />
Lägg till en navigeringslänk till komponenten DaleksMain i NavMenu.razor:
<div class="nav-item px-3">
    <NavLink class="nav-link" href="daleks-main">
        <span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Daleks
    </NavLink>
</div>
              CascadingValueSource<TValue>Eftersom typen 's i det här exemplet (NotifyingDalek) är en klasstyp kan du uppfylla praktiskt taget alla krav för funktionsspecifikation för tillståndshantering. Prenumerationer skapar dock omkostnader och minskar prestanda, så jämför prestandan för den här metoden i din app och jämför den med andra tillståndshanteringsmetoder innan du använder den i en produktionsapp med begränsade bearbetnings- och minnesresurser.
Alla ändringar i tillståndet (vilken egenskapsvärdeändring som helst i klassen) orsakar att alla prenumererade komponenter renderas om, oavsett vilken del av tillståndet de använder. Undvik att skapa en enda stor klass som representerar hela det globala programtillståndet. Skapa i stället detaljerade klasser och koppla dem separat med specifika prenumerationer till sammanhängande parametrar, vilket säkerställer att endast komponenter som prenumererar på en viss del av programtillståndet påverkas av ändringar.
              CascadingValue komponent
En överordnad komponent ger ett sammanhängande värde med hjälp av Blazor ramverkets CascadingValue komponent, som omsluter ett underträd i en komponenthierarki och tillhandahåller ett enda värde till alla komponenter i dess underträd.
I följande exempel visas flödet av temainformation i komponenthierarkin för att tillhandahålla en CSS-stilklass till knappar i underordnade komponenter.
Följande ThemeInfo C#-klass anger temainformationen.
Obs
För exemplen i det här avsnittet är appens namnområde BlazorSample. När du experimenterar med koden i din egen exempelapp ändrar du appens namnområde till exempelappens namnområde.
              ThemeInfo.cs:
namespace BlazorSample;
public class ThemeInfo
{
    public string? ButtonClass { get; set; }
}
namespace BlazorSample;
public class ThemeInfo
{
    public string? ButtonClass { get; set; }
}
namespace BlazorSample.UIThemeClasses;
public class ThemeInfo
{
    public string? ButtonClass { get; set; }
}
namespace BlazorSample.UIThemeClasses;
public class ThemeInfo
{
    public string? ButtonClass { get; set; }
}
namespace BlazorSample.UIThemeClasses
{
    public class ThemeInfo
    {
        public string ButtonClass { get; set; }
    }
}
namespace BlazorSample.UIThemeClasses
{
    public class ThemeInfo
    {
        public string ButtonClass { get; set; }
    }
}
Följande layoutkomponent anger temainformation (ThemeInfo) som ett sammanhängande värde för alla komponenter som utgör layouttexten för egenskapen Body. 
              ButtonClass tilldelas värdet btn-success, vilket är en Bootstrap-knappstil. Alla underordnade komponenter i komponenthierarkin kan använda egenskapen ButtonClass via det ThemeInfo sammanhängande värdet.
              MainLayout.razor:
@inherits LayoutComponentBase
<div class="page">
    <div class="sidebar">
        <NavMenu />
    </div>
    <main>
        <div class="top-row px-4">
            <a href="https://free.blessedness.top/aspnet/core/" target="_blank">About</a>
        </div>
        <CascadingValue Value="theme">
            <article class="content px-4">
                @Body
            </article>
        </CascadingValue>
    </main>
</div>
<div id="blazor-error-ui" data-nosnippet>
    An unhandled error has occurred.
    <a href="." class="reload">Reload</a>
    <span class="dismiss">🗙</span>
</div>
@code {
    private ThemeInfo theme = new() { ButtonClass = "btn-success" };
}
@inherits LayoutComponentBase
<div class="page">
    <div class="sidebar">
        <NavMenu />
    </div>
    <main>
        <div class="top-row px-4">
            <a href="https://free.blessedness.top/aspnet/core/" target="_blank">About</a>
        </div>
        <CascadingValue Value="theme">
            <article class="content px-4">
                @Body
            </article>
        </CascadingValue>
    </main>
</div>
<div id="blazor-error-ui" data-nosnippet>
    An unhandled error has occurred.
    <a href="" class="reload">Reload</a>
    <a class="dismiss">🗙</a>
</div>
@code {
    private ThemeInfo theme = new() { ButtonClass = "btn-success" };
}
@inherits LayoutComponentBase
@using BlazorSample.UIThemeClasses
<div class="page">
    <div class="sidebar">
        <NavMenu />
    </div>
    <main>
        <div class="top-row px-4">
            <a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
        </div>
        <CascadingValue Value="@theme">
            <article class="content px-4">
                @Body
            </article>
        </CascadingValue>
    </main>
</div>
@code {
    private ThemeInfo theme = new() { ButtonClass = "btn-success" };
}
@inherits LayoutComponentBase
@using BlazorSample.UIThemeClasses
<div class="page">
    <div class="sidebar">
        <NavMenu />
    </div>
    <main>
        <CascadingValue Value="@theme">
            <div class="content px-4">
                @Body
            </div>
        </CascadingValue>
    </main>
</div>
@code {
    private ThemeInfo theme = new() { ButtonClass = "btn-success" };
}
@inherits LayoutComponentBase
@using BlazorSample.UIThemeClasses
<div class="page">
    <div class="sidebar">
        <NavMenu />
    </div>
    <div class="main">
        <CascadingValue Value="@theme">
            <div class="content px-4">
                @Body
            </div>
        </CascadingValue>
    </div>
</div>
@code {
    private ThemeInfo theme = new() { ButtonClass = "btn-success" };
}
@inherits LayoutComponentBase
@using BlazorSample.UIThemeClasses
<div class="sidebar">
    <NavMenu />
</div>
<div class="main">
    <CascadingValue Value="theme">
        <div class="content px-4">
            @Body
        </div>
    </CascadingValue>
</div>
@code {
    private ThemeInfo theme = new ThemeInfo { ButtonClass = "btn-success" };
}
Blazor Web Appger alternativa metoder för värden i en kaskad som gäller mer allmänt för appen än att tillhandahålla dem via en enda layoutfil.
- Omslut - Routeskomponenten i en- CascadingValuekomponent för att ange data som ett sammanhängande värde för alla appens komponenter.- Följande exempel överlappar - ThemeInfodata från komponenten- Routes.- Routes.razor:- <CascadingValue Value="theme"> <Router ...> ... </Router> </CascadingValue> @code { private ThemeInfo theme = new() { ButtonClass = "btn-success" }; }- Obs - Det är inte möjligt att omsluta komponentinstansen - Routesi komponenten- App(- Components/App.razor) med en- CascadingValue-komponent.
- Ange ett sammanhängande värde på rotnivå som en tjänst genom att anropa AddCascadingValue-tilläggsmetoden i servicesamlingsverktyget. - I följande exempel kaskaderar data från - ThemeInfo-filen till- Program-filen.- Program.cs- builder.Services.AddCascadingValue(sp => new ThemeInfo() { ButtonClass = "btn-primary" });
Mer information finns i följande avsnitt i den här artikeln:
              [CascadingParameter]-attributet
Om du vill använda sammanhängande värden deklarerar underordnade komponenter sammanhängande parametrar med hjälp av attributet [CascadingParameter]. Sammanhängande värden är bundna till sammanhängande parametrar efter typ. Sammanhängande flera värden av samma typ beskrivs i avsnittet Cascade multiple values senare i den här artikeln.
Följande komponent binder det kaskaderande värdet ThemeInfo till en kaskaderande parameter, valfritt med samma namn som ThemeInfo. Parametern används för att ange CSS-klassen för knappen Increment Counter (Themed).
              ThemedCounter.razor:
@page "/themed-counter"
<PageTitle>Themed Counter</PageTitle>
<h1>Themed Counter Example</h1>
<p>Current count: @currentCount</p>
<p>
    <button @onclick="IncrementCount">
        Increment Counter (Unthemed)
    </button>
</p>
<p>
    <button 
        class="btn @(ThemeInfo is not null ? ThemeInfo.ButtonClass : string.Empty)" 
        @onclick="IncrementCount">
        Increment Counter (Themed)
    </button>
</p>
@code {
    private int currentCount = 0;
    [CascadingParameter]
    protected ThemeInfo? ThemeInfo { get; set; }
    private void IncrementCount() => currentCount++;
}
@page "/themed-counter"
<PageTitle>Themed Counter</PageTitle>
<h1>Themed Counter Example</h1>
<p>Current count: @currentCount</p>
<p>
    <button @onclick="IncrementCount">
        Increment Counter (Unthemed)
    </button>
</p>
<p>
    <button 
        class="btn @(ThemeInfo is not null ? ThemeInfo.ButtonClass : string.Empty)" 
        @onclick="IncrementCount">
        Increment Counter (Themed)
    </button>
</p>
@code {
    private int currentCount = 0;
    [CascadingParameter]
    protected ThemeInfo? ThemeInfo { get; set; }
    private void IncrementCount() => currentCount++;
}
@page "/themed-counter"
@using BlazorSample.UIThemeClasses
<h1>Themed Counter</h1>
<p>Current count: @currentCount</p>
<p>
    <button @onclick="IncrementCount">
        Increment Counter (Unthemed)
    </button>
</p>
<p>
    <button 
        class="btn @(ThemeInfo is not null ? ThemeInfo.ButtonClass : string.Empty)" 
        @onclick="IncrementCount">
        Increment Counter (Themed)
    </button>
</p>
@code {
    private int currentCount = 0;
    [CascadingParameter]
    protected ThemeInfo? ThemeInfo { get; set; }
    private void IncrementCount()
    {
        currentCount++;
    }
}
@page "/themed-counter"
@using BlazorSample.UIThemeClasses
<h1>Themed Counter</h1>
<p>Current count: @currentCount</p>
<p>
    <button @onclick="IncrementCount">
        Increment Counter (Unthemed)
    </button>
</p>
<p>
    <button 
        class="btn @(ThemeInfo is not null ? ThemeInfo.ButtonClass : string.Empty)" 
        @onclick="IncrementCount">
        Increment Counter (Themed)
    </button>
</p>
@code {
    private int currentCount = 0;
    [CascadingParameter]
    protected ThemeInfo? ThemeInfo { get; set; }
    private void IncrementCount()
    {
        currentCount++;
    }
}
@page "/themed-counter"
@using BlazorSample.UIThemeClasses
<h1>Themed Counter</h1>
<p>Current count: @currentCount</p>
<p>
    <button @onclick="IncrementCount">
        Increment Counter (Unthemed)
    </button>
</p>
<p>
    <button class="btn @ThemeInfo.ButtonClass" @onclick="IncrementCount">
        Increment Counter (Themed)
    </button>
</p>
@code {
    private int currentCount = 0;
    [CascadingParameter]
    protected ThemeInfo ThemeInfo { get; set; }
    private void IncrementCount()
    {
        currentCount++;
    }
}
@page "/themed-counter"
@using BlazorSample.UIThemeClasses
<h1>Themed Counter</h1>
<p>Current count: @currentCount</p>
<p>
    <button @onclick="IncrementCount">
        Increment Counter (Unthemed)
    </button>
</p>
<p>
    <button class="btn @ThemeInfo.ButtonClass" @onclick="IncrementCount">
        Increment Counter (Themed)
    </button>
</p>
@code {
    private int currentCount = 0;
    [CascadingParameter]
    protected ThemeInfo ThemeInfo { get; set; }
    private void IncrementCount()
    {
        currentCount++;
    }
}
På samma sätt som en vanlig komponentparameter återskapas komponenter som accepterar en sammanhängande parameter när det sammanhängande värdet ändras. Om du till exempel konfigurerar en annan temainstans orsakar det att ThemedCounter-komponenten från komponent CascadingValue sektionen återskapas.
              MainLayout.razor:
<main>
    <div class="top-row px-4">
        <a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
    </div>
    <CascadingValue Value="theme">
        <article class="content px-4">
            @Body
        </article>
    </CascadingValue>
    <button @onclick="ChangeToDarkTheme">Dark mode</button>
</main>
@code {
    private ThemeInfo theme = new() { ButtonClass = "btn-success" };
    private void ChangeToDarkTheme()
    {
        theme = new() { ButtonClass = "btn-secondary" };
    }
}
CascadingValue<TValue>.IsFixed kan användas för att indikera att en sammanhängande parameter inte ändras efter initieringen.
Sammanhängande värden/parametrar och återgivningslägesgränser
Sammanhängande parametrar skickar inte data över gränserna för återgivningsläge:
- Interaktiva sessioner körs i en annan kontext än de sidor som använder statisk återgivning på serversidan (statisk SSR). Det finns inget krav på att servern som producerar sidan ens är samma dator som är värd för en senare interaktiv serversession, inklusive för WebAssembly-komponenter där servern är en annan dator än klienten. Fördelen med statisk återgivning på serversidan (statisk SSR) är att få full prestanda för ren tillståndslös HTML-rendering. 
- Tillstånd som korsar gränsen mellan statisk och interaktiv återgivning måste vara serialiserbart. Komponenter är godtyckliga objekt som refererar till en omfattande kedja av andra objekt, inklusive renderaren, DI-containern och varje DI-tjänstinstans. Du måste uttryckligen orsaka att tillståndet serialiseras från statisk SSR för att göra det tillgängligt i efterföljande interaktivt renderade komponenter. Två metoder används: - Via det Blazor ramverket serialiseras parametrar som skickas över en statisk SSR till en interaktiv återgivningsgräns automatiskt om de är JSON-serialiserbara eller om ett fel utlöses.
- Tillståndet som lagras i beständigt komponenttillstånd serialiseras och återställs automatiskt om det är JSON-serialiserbart, eller om ett fel utlöses.
 
Sammanhängande parametrar är inte JSON-serialiserbara eftersom de typiska användningsmönstren för sammanhängande parametrar liknar DI-tjänster. Det finns ofta plattformsspecifika varianter av sammanhängande parametrar, så det skulle inte vara till någon hjälp för utvecklare om ramverket hindrade utvecklare från att ha server-interaktiva specifika versioner eller WebAssembly-specifika versioner. Dessutom är många sammanhängande parametervärden i allmänhet inte serialiserbara, så det skulle vara opraktiskt att uppdatera befintliga appar om du var tvungen att sluta använda alla icke-numeriska sammanhängande parametervärden.
Rekommendationer:
- Om du behöver göra tillståndet tillgängligt för alla interaktiva komponenter som en sammanhängande parameter rekommenderar vi att du använder sammanhängande värden på rotnivå eller sammanhängande värden på rotnivå med meddelanden. Ett fabriksmönster är tillgängligt och appen kan generera uppdaterade värden efter appstart. Sammanhängande värden på rotnivå är tillgängliga för alla komponenter, inklusive interaktiva komponenter, eftersom de bearbetas som DI-tjänster. 
- För komponentbiblioteksförfattare kan du skapa en tilläggsmetod för bibliotekskonsumenter som liknar följande: - builder.Services.AddLibraryCascadingParameters();- Instruera utvecklare att anropa tilläggsmetoden. Det här är ett bra alternativ till att instruera dem att lägga till en - <RootComponent>komponent i sin- MainLayoutkomponent.
Kaskadera flera värden
Om du vill överlappa flera värden av samma typ i samma underträd anger du en unik Name sträng för varje CascadingValue komponent och motsvarande [CascadingParameter] attribut.
I följande exempel överlappar två CascadingValue komponenter olika instanser av CascadingType:
<CascadingValue Value="parentCascadeParameter1" Name="CascadeParam1">
    <CascadingValue Value="ParentCascadeParameter2" Name="CascadeParam2">
        ...
    </CascadingValue>
</CascadingValue>
@code {
    private CascadingType? parentCascadeParameter1;
    [Parameter]
    public CascadingType? ParentCascadeParameter2 { get; set; }
}
I en underordnad komponent tar de kaskadparametrarna emot sina kaskadvärden från den överordnade komponenten via Name:
@code {
    [CascadingParameter(Name = "CascadeParam1")]
    protected CascadingType? ChildCascadeParameter1 { get; set; }
    [CascadingParameter(Name = "CascadeParam2")]
    protected CascadingType? ChildCascadeParameter2 { get; set; }
}
Skicka data över en komponenthierarki
Sammanhängande parametrar gör det också möjligt för komponenter att skicka data över en komponenthierarki. Överväg följande exempel på flikuppsättningen för användargränssnittet, där en flikuppsättningskomponent underhåller en serie enskilda flikar.
Obs
För exemplen i det här avsnittet är appens namnområde BlazorSample. När du experimenterar med koden i din egen exempelapp ändrar du namnområdet till exempelappens namnområde.
Skapa ett ITab gränssnitt som flikar implementerar i en mapp med namnet UIInterfaces.
              UIInterfaces/ITab.cs:
using Microsoft.AspNetCore.Components;
namespace BlazorSample.UIInterfaces;
public interface ITab
{
    RenderFragment ChildContent { get; }
}
Obs
Mer information om RenderFragmentfinns i ASP.NET Core Razor-komponenter.
Den följande TabSet-komponenten håller en uppsättning flikar. Tabbuppsättningens Tab komponenter, som skapas senare i det här avsnittet, anger listobjekten (<li>...</li>) för listan (<ul>...</ul>).
Underordnade Tab-komponenter passeras inte uttryckligen som parametrar till TabSet. I stället är komponenterna i Tab en del av innehållet för TabSet. Men TabSet behöver fortfarande en referens till varje Tab komponent så att den kan återge rubrikerna och den aktiva fliken. Om du vill aktivera den här samordningen utan att behöva ytterligare kod kan TabSet komponenten ange sig själv som ett sammanhängande värde som sedan hämtas av de underordnade Tab komponenterna.
              TabSet.razor:
@using BlazorSample.UIInterfaces
<!-- Display the tab headers -->
<CascadingValue Value="this">
    <ul class="nav nav-tabs">
        @ChildContent
    </ul>
</CascadingValue>
<!-- Display body for only the active tab -->
<div class="nav-tabs-body p-4">
    @ActiveTab?.ChildContent
</div>
@code {
    [Parameter]
    public RenderFragment? ChildContent { get; set; }
    public ITab? ActiveTab { get; private set; }
    public void AddTab(ITab tab)
    {
        if (ActiveTab is null)
        {
            SetActiveTab(tab);
        }
    }
    public void SetActiveTab(ITab tab)
    {
        if (ActiveTab != tab)
        {
            ActiveTab = tab;
            StateHasChanged();
        }
    }
}
Underordnade Tab komponenter avbildar de innehållande TabSet som en sammanhängande parameter. De Tab komponenterna lägger till sig själva i TabSet och samordnar för att ange den aktiva fliken.
              Tab.razor:
@using BlazorSample.UIInterfaces
@implements ITab
<li>
    <a @onclick="ActivateTab" class="nav-link @TitleCssClass" role="button">
        @Title
    </a>
</li>
@code {
    [CascadingParameter]
    public TabSet? ContainerTabSet { get; set; }
    [Parameter]
    public string? Title { get; set; }
    [Parameter]
    public RenderFragment? ChildContent { get; set; }
    private string? TitleCssClass => 
        ContainerTabSet?.ActiveTab == this ? "active" : null;
    protected override void OnInitialized()
    {
        ContainerTabSet?.AddTab(this);
    }
    private void ActivateTab()
    {
        ContainerTabSet?.SetActiveTab(this);
    }
}
Följande ExampleTabSet komponent använder komponenten TabSet, som innehåller tre Tab komponenter.
              ExampleTabSet.razor:
@page "/example-tab-set"
<TabSet>
    <Tab Title="First tab">
        <h4>Greetings from the first tab!</h4>
        <label>
            <input type="checkbox" @bind="showThirdTab" />
            Toggle third tab
        </label>
    </Tab>
    <Tab Title="Second tab">
        <h4>Hello from the second tab!</h4>
    </Tab>
    @if (showThirdTab)
    {
        <Tab Title="Third tab">
            <h4>Welcome to the disappearing third tab!</h4>
            <p>Toggle this tab from the first tab.</p>
        </Tab>
    }
</TabSet>
@code {
    private bool showThirdTab;
}
Ytterligare resurser
ASP.NET Core