Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Not
Bu, bu makalenin en son sürümü değildir. Geçerli sürüm için bu makalenin .NET 10 sürümüne bakın.
Uyarı
ASP.NET Core'un bu sürümü artık desteklenmiyor. Daha fazla bilgi için bkz . .NET ve .NET Core Destek İlkesi. Geçerli sürüm için bu makalenin .NET 9 sürümüne bakın.
Bu makalede, bir ata Razor bileşeninden alt bileşenlere veri akışı açıklanmaktadır.
Basamaklı değerler ve parametreler , bir alt bileşen bileşeninden herhangi bir sayıda alt bileşene veri akışı yapmak için uygun bir yol sağlar. Bileşen parametrelerinden farklı olarak, basamaklı değerler ve parametreler, verilerin kullanıldığı her alt bileşen için bir öznitelik ataması gerektirmez. Basamaklı değerler ve parametreler, bileşenlerin bir bileşen hiyerarşisinde birbirleriyle eşgüdüm sağlamasına da olanak sağlar.
Not
Bu makaledeki kod örnekleri, .NET 6 veya sonraki sürümlerindeki ASP.NET Core'da desteklenen null atanabilir başvuru türlerini (NTS) ve .NET derleyici null durum statik analizini benimser. .NET 5 veya önceki sürümleri hedeflerken, makalenin örneklerindeki ?, CascadingType?, @ActiveTab?, RenderFragment?, ITab? ve TabSet? türlerinden null tür atamasını (string?) kaldırın.
Kök düzeyinde basamaklı değerler
Kök düzeyinde basamaklı değerler tüm bileşen hiyerarşisi için kaydedilebilir. Güncelleştirme bildirimleri için adlandırılmış basamaklı değerler ve abonelikler desteklenir.
Bu bölümün örneklerinde aşağıdaki sınıf kullanılmıştır.
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; }
}
Aşağıdaki kayıtlar ile uygulamanın Program dosyasında AddCascadingValueyapılır:
-
Dalekiçin bir özellik değeriUnitsile sabit basamaklı değer olarak kaydedilir. - için
Dalekfarklı bir özellik değerine sahip ikinciUnitskayıt "AlphaGroup" olarak adlandırılır.
builder.Services.AddCascadingValue(sp => new Dalek { Units = 123 });
builder.Services.AddCascadingValue("AlphaGroup", sp => new Dalek { Units = 456 });
Aşağıdaki Daleks bileşen basamaklı değerleri görüntüler.
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]
private 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]
private Dalek? Dalek { get; set; }
[CascadingParameter(Name = "AlphaGroup")]
public Dalek? AlphaGroupDalek { get; set; }
}
Aşağıdaki örnekte, Dalek kullanılarak CascadingValueSource<T>basamaklı bir değer olarak kaydedilir; burada <T> türüdür. bayrağı değerin isFixed sabit olup olmadığını gösterir. ise false, tüm alıcılar güncelleştirme bildirimlerine abone olur. Abonelikler ek yük oluşturur ve performansı azaltır, dolayısıyla değer değişmezse olarak ayarlanır isFixedtrue .
builder.Services.AddCascadingValue(sp =>
{
var dalek = new Dalek { Units = 789 };
var source = new CascadingValueSource<Dalek>(dalek, isFixed: false);
return source;
});
Uyarı
Bir bileşen türünün kök düzeyinde basamaklı değer olarak kaydedilmesi, tür için ek hizmetler kaydetmez veya bileşende hizmet etkinleştirmesine izin vermez.
Gerekli hizmetleri basamaklı değerlerden ayrı olarak değerlendirin ve bunları basamaklı türden ayrı olarak kaydedin.
Bir bileşen türünü basamaklı değer olarak kaydetmek için kullanmaktan AddCascadingValue kaçının. Bunun yerine bileşenini (<Router>...</Router>) bileşeniyle sarmalayıp RoutesComponents/Routes.razor genel etkileşimli sunucu tarafı işlemeyi (etkileşimli SSR) benimseyin. Bir örnek için bileşen bölümüne bakınCascadingValue.
Bildirimler içeren kök düzeyinde basamaklı değerler
Güncelleştirme bildirimleri vermek için NotifyChangedAsync'i çağırarak, birden çok Razor bileşen abonesine basamaklı bir değerin değiştiğini bildirmek için kullanılabilir. Statik sunucu tarafı işlemeyi (statik SSR) benimseyen aboneler için bildirimler mümkün değildir, bu nedenle abonelerin etkileşimli bir işleme modunu benimsemesi gerekir.
Aşağıdaki örnekte:
-
NotifyingDalekINotifyPropertyChanged bir özellik değerinin değiştiğini istemcilere bildirmek için uygular.UnitsÖzelliği ayarlandığında , PropertyChangedEventHandler (PropertyChanged) çağrılır. - Aboneler tarafından, işlem gecikmesi simüle edilerek yöntemin
SetUnitsToOneThousandAsyncile başlangıç değerini 1.000 olarak ayarlamak içinUnitstetiklenebilir.
Üretim kodu için, durum değişikliğinin (sınıfın herhangi bir özellik değeri değişikliği), durumun hangi kısmını kullandıklarına bakılmaksızın abone olunan tüm bileşenlerin yeniden render edilmesine neden olduğunu unutmayın. Yalnızca uygulama durumunun belirli bir bölümüne abone olan bileşenlerin değişikliklerden etkilenmesini sağlamak için ayrıntılı sınıflar oluşturmanızı ve bunları belirli aboneliklerle birlikte basamaklı olarak oluşturmanızı öneririz.
Not
Sunucu ve istemci (Blazor Web App) projelerinden oluşan bir .Client çözüm için, aşağıdaki NotifyingDalek.cs dosyası .Client projesine yerleştirilir.
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;
}
}
Aşağıdaki CascadingStateServiceCollectionExtensions, CascadingValueSource<TValue> uygulayan bir türden bir INotifyPropertyChanged oluşturur.
Not
Sunucu ve istemci (Blazor Web App) projelerinden oluşan bir .Client çözüm için, aşağıdaki CascadingStateServiceCollectionExtensions.cs dosyası .Client projesine yerleştirilir.
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;
}
}
}
Türün PropertyChangedEventHandler (HandlePropertyChanged), abonelere basamaklı değerin değiştiğini bildirmek için CascadingValueSource<TValue>'nin NotifyChangedAsync yöntemini çağırır.
Task
NotifyChangedAsync çağrısı yalnızca zaman uyumlu bağlama gönderme süresini temsil ettiği için atılır. Özel durumlar, güncelleştirmeyi alırken hangi bileşenin atıldığı bağlamında işleyiciye gönderilerek dahili olarak işlenir. Bu, bildirim alıcılarının içinde meydana gelen özel durumlar hakkında bilgilendirilmeyen bir mekanizma olan CascadingValue<TValue> ile özel durumların işlenme şekline benzer.
Dispose yönteminde, bellek sızıntısını önlemek için olay işleyicisi bağlantısı kesilir.
Program dosyasında, NotifyingDalek ilk CascadingValueSource<TValue> değeri 888 birim olan bir Unit oluşturmak için geçirilir:
builder.Services.AddNotifyingCascadingValue(new NotifyingDalek() { Units = 888 });
Not
Sunucu ve istemci (Blazor Web App) projelerinden oluşan bir .Client çözüm için, yukarıdaki kod her projenin Program dosyasına yerleştirilir.
Abonelere NotifyingDalek.Units değerinin değişmesinin nasıl bildirim gönderdiğini göstermek için aşağıdaki bileşen kullanılır.
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]
private 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();
}
}
}
Birden çok abone bildirimini göstermek için aşağıdaki DaleksMain bileşen üç Daleks bileşeni işler. Bir Units bileşenin birim sayısı (Dalek) güncelleştirildiğinde, diğer iki Dalek bileşen abonesi güncelleştirilir.
DaleksMain.razor:
@page "/daleks-main"
<PageTitle>Daleks Main</PageTitle>
<h1>Daleks Main</h1>
<Daleks />
<Daleks />
<Daleks />
DaleksMain bileşenine NavMenu.razor içindeki bir gezinti bağlantısı ekleyin.
<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>
Bu örnekteki CascadingValueSource<TValue>(NotifyingDalek) türü bir sınıf türü olduğundan, hemen hemen tüm durum yönetimi özellik belirtim gereksinimlerini karşılayabilirsiniz. Ancak abonelikler ek yük oluşturur ve performansı azaltır, bu nedenle uygulamanızda bu yaklaşımın performansını karşılaştırın ve kısıtlanmış işleme ve bellek kaynaklarına sahip bir üretim uygulamasında benimsemeden önce diğer durum yönetimi yaklaşımlarıyla karşılaştırın.
Durumundaki herhangi bir değişiklik (sınıfın herhangi bir özellik değeri değişikliği), durumun hangi bölümünü kullandıklarından bağımsız olarak abone olunan tüm bileşenlerin yeniden kullanılmasına neden olur. Tüm genel uygulama durumunu temsil eden tek bir büyük sınıf oluşturmaktan kaçının. Bunun yerine, ayrıntılı sınıflar oluşturun ve bunları belirli aboneliklerle art arda parametrelere basamaklayarak yalnızca uygulama durumunun belirli bir bölümüne abone olan bileşenlerin değişikliklerden etkilenmesini sağlayın.
CascadingValue bileşeni
Bir üst bileşen, bir bileşen hiyerarşisinin Blazor alt ağacını sarmalayan ve alt ağacı içindeki tüm bileşenlere tek bir değer sağlayan çerçevenin CascadingValue bileşenini kullanarak basamaklı bir değer sağlar.
Aşağıdaki örnek, alt bileşenlerdeki düğmelere CSS stil sınıfı sağlamak için bileşen hiyerarşisinde tema bilgilerinin akışını gösterir.
Aşağıdaki ThemeInfo C# sınıfı tema bilgilerini belirtir.
Not
Bu bölümdeki örnekler için uygulamanın ad alanı şeklindedir BlazorSample. Kendi örnek uygulamanızdaki kodla denemeler yaparken, uygulamanın ad alanını örnek uygulamanızın ad alanıyla değiştirin.
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; }
}
}
Aşağıdaki düzen bileşeni , tema bilgilerini (ThemeInfo) özelliğin düzen gövdesini Body oluşturan tüm bileşenler için basamaklı değer olarak belirtir.
ButtonClass bir Bootstrap düğme stili olan değeri btn-successatanır. Bileşen hiyerarşisindeki herhangi bir alt bileşen, basamaklı değer aracılığıyla ButtonClass özelliğini kullanabilirThemeInfo.
MainLayout.razor:
@inherits LayoutComponentBase
<div class="page">
<div class="sidebar">
<NavMenu />
</div>
<main>
<div class="top-row px-4">
<a href="https://learn.microsoft.com/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://learn.microsoft.com/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 Apps, uygulamaya tek bir düzen dosyası aracılığıyla vermekten daha geniş kapsamlı olarak uygulanan basamaklı değerler için alternatif yaklaşımlar sağlar:
Verileri uygulamanın tüm bileşenleri için basamaklı değer olarak belirtmek üzere bileşenin işaretlemesini
RoutesbirCascadingValuebileşene sarmalar.Aşağıdaki örnek, bileşenden
ThemeInfoverileri basamaklarRoutes.Routes.razor:<CascadingValue Value="theme"> <Router ...> ... </Router> </CascadingValue> @code { private ThemeInfo theme = new() { ButtonClass = "btn-success" }; }Not
Bileşendeki
Routes(App) bileşen örneğini birComponents/App.razorbileşenle sarmalamaCascadingValuedesteklenmez.belirtin.
Aşağıdaki örnek, dosyadaki
ThemeInfoverileri basamaklarProgram.Program.csbuilder.Services.AddCascadingValue(sp => new ThemeInfo() { ButtonClass = "btn-primary" });
Daha fazla bilgi için bu makalenin aşağıdaki bölümlerine bakın:
[CascadingParameter] özniteliği
Basamaklı değerleri kullanmak için, alt bileşenler özniteliğini [CascadingParameter]kullanarak basamaklı parametreler bildirir. Basamaklı değerler türe göre basamaklı parametrelere bağlıdır. Aynı türdeki birden çok değeri basamaklama, bu makalenin devamında yer alan Birden çok değeri basamaklama bölümünde ele alınmıştır.
private erişim belirleyici, parametrenin kapsamı çoğu durumda yalnızca bileşenin sınıfı içinde kullanılacak şekilde ayarlanması gerektiğinden, geçişli parametreler için tavsiye edilir. Alt sınıflama gerektiğinde erişim değiştiricisini protected kullanın.
Aşağıdaki bileşen, basamaklı değeri isteğe bağlı olarak aynı adı ThemeInfokullanarak basamaklı bir parametreye bağlarThemeInfo. parametresi, düğmenin CSS sınıfını Increment Counter (Themed) ayarlamak için kullanılır.
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]
private 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]
private 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]
private 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]
private 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]
private 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]
private ThemeInfo ThemeInfo { get; set; }
private void IncrementCount()
{
currentCount++;
}
}
Normal bileşen parametresine benzer şekilde, basamaklı bir parametreyi kabul eden bileşenler, basamaklı değer değiştirildiğinde yeniden oluşturulur. Örneğin, farklı bir tema örneğinin yapılandırılması bileşenin ThemedCounter bileşenCascadingValue yeniden yapılandırılmasına neden olur.
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 , basamaklı parametrenin başlatmadan sonra değişmediğini belirtmek için kullanılabilir.
Basamaklı değerler/parametreler ve işleme modu sınırları
Basamaklı parametreler işleme modu sınırları arasında veri geçirmez:
Etkileşimli oturumlar, statik sunucu tarafı işleme (statik SSR) kullanan sayfalardan farklı bir bağlamda çalışır. Sayfayı üreten sunucunun, sunucunun istemciden farklı bir makine olduğu WebAssembly bileşenleri de dahil olmak üzere daha sonraki Etkileşimli Sunucu oturumlarını barındıran makineyle aynı olması gerekmez. Statik sunucu tarafı işlemenin (statik SSR) avantajı, durum bilgisi olmayan html işlemenin tam performansını elde etmektir.
Statik ve etkileşimli işleme arasındaki sınırı geçen durum serileştirilebilir olmalıdır. Bileşenler işleyici, DI kapsayıcısı ve her DI hizmeti örneği dahil olmak üzere diğer nesnelerin geniş bir zincirine başvuran rastgele nesnelerdir. Durumu etkileşimli olarak işlenen sonraki bileşenlerde kullanılabilir hale getirmek için statik SSR'den seri hale getirilmesine açıkça neden olmanız gerekir. İki yaklaşım benimsenmiştir:
- Blazor Çerçeve aracılığıyla, statik SSR üzerinden etkileşimli işleme sınırına geçirilen parametreler JSON serileştirilebilir olduğunda veya bir hata oluştuğunda otomatik olarak serileştirilir.
- Kalıcı Bileşen Durumunda depolanan durum, JSON serileştirilebilirse veya bir hata oluşursa otomatik olarak serileştirilir ve kurtarılır.
Basamaklı parametreler için tipik kullanım desenleri BIRAZ DI hizmetlerine benzer olduğundan, basamaklı parametreler JSON serileştirilebilir değildir. Genellikle basamaklı parametrelerin platforma özgü çeşitleri vardır, bu nedenle çerçeve geliştiricilerin sunucuya etkileşimli özel sürümlere veya WebAssembly'ye özgü sürümlere sahip olmasını durdurursa geliştiricilere yardımcı olmaz. Ayrıca, genel olarak birçok basamaklı parametre değeri serileştirilebilir değildir, bu nedenle tüm sıralı hale getirilemez basamaklı parametre değerlerini kullanmayı bırakmanız gerekiyorsa mevcut uygulamaları güncelleştirmek pratik olmaz.
Öneriler:
Durumu basamaklı parametre olarak tüm etkileşimli bileşenler için kullanılabilir hale getirmeniz gerekiyorsa, bildirimlerle kök düzeyinde basamaklı değerleri veya kök düzeyinde basamaklı değerleri kullanmanızı öneririz. Bir fabrika düzeni kullanılabilir ve uygulama, uygulama başlangıcından sonra güncelleştirilmiş değerler yayabilir. Di hizmetleri olarak işlendiği için, kök düzeyinde basamaklı değerler etkileşimli bileşenler de dahil olmak üzere tüm bileşenler tarafından kullanılabilir.
Bileşen kitaplığı yazarları için, kitaplık tüketicileri için aşağıdakine benzer bir uzantı yöntemi oluşturabilirsiniz:
builder.Services.AddLibraryCascadingParameters();Geliştiricilere uzantı yönteminizi çağırmalarını sağlayın. Bu, bileşenlerine bir bileşen eklemelerini
<RootComponent>bildirmek için birMainLayoutses alternatifidir.
Birden çok değeri art arda basamaklama
Aynı alt ağaç içinde aynı türdeki birden çok değeri art arda eklemek için, her Name bileşene ve ilgili CascadingValue benzersiz [CascadingParameter] bir dize sağlayın.
Aşağıdaki örnekte, iki CascadingValue bileşen farklı örneklerini art arda sıralar CascadingType:
<CascadingValue Value="parentCascadeParameter1" Name="CascadeParam1">
<CascadingValue Value="ParentCascadeParameter2" Name="CascadeParam2">
...
</CascadingValue>
</CascadingValue>
@code {
private CascadingType? parentCascadeParameter1;
[Parameter]
public CascadingType? ParentCascadeParameter2 { get; set; }
}
Alt bileşende basamaklı parametreler, basamaklı değerlerini ile ata bileşeninden Namealır:
@code {
[CascadingParameter(Name = "CascadeParam1")]
protected CascadingType? ChildCascadeParameter1 { get; set; }
[CascadingParameter(Name = "CascadeParam2")]
protected CascadingType? ChildCascadeParameter2 { get; set; }
}
Bileşen hiyerarşisi boyunca verileri geçirme
Basamaklı parametreler, bileşenlerin bir bileşen hiyerarşisinde veri geçirmesini de sağlar. Bir sekme kümesi bileşeninin bir dizi ayrı sekmeyi barındırdığı aşağıdaki kullanıcı arabirimi sekmesi kümesi örneğini göz önünde bulundurun.
Not
Bu bölümdeki örnekler için uygulamanın ad alanı şeklindedir BlazorSample. Kendi örnek uygulamanızdaki kodla denemeler yaparken, ad alanını örnek uygulamanızın ad alanı olarak değiştirin.
Sekmelerin adlı ITabbir UIInterfaces klasörde uyguladığı bir arabirim oluşturun.
UIInterfaces/ITab.cs:
using Microsoft.AspNetCore.Components;
namespace BlazorSample.UIInterfaces;
public interface ITab
{
RenderFragment ChildContent { get; }
}
Not
hakkında RenderFragmentdaha fazla bilgi için bkz . ASP.NET Core Razor bileşenleri.
Aşağıdaki TabSet bileşen bir sekme kümesi tutar. Bu bölümün ilerleyen bölümlerinde oluşturulan sekme kümesinin Tab bileşenleri, liste () için liste öğelerini (<li>...</li><ul>...</ul>) sağlayın.
Alt Tab bileşenler açıkça parametresi olarak geçirilmemektedir TabSet. Bunun yerine, alt Tab bileşenler öğesinin alt içeriğinin TabSetbir parçasıdır. Ancak, TabSet üst bilgileri işleyebilmesi ve etkin sekmeyi görüntüleyebilmesi için her Tab bileşenine bir başvuru gerekir. Ek kod gerektirmeden bu koordinasyonu etkinleştirmek için, TabSet bileşeni kendini basamaklı bir değer olarak tanımlayarak'ü sağlayabilir ve bu daha sonra Tab alt bileşenleri tarafından alınır.
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();
}
}
}
Tab Alt bileşenler, içeren TabSet öğesini basamaklı parametre olarak yakalar.
Tab Bileşenler, etkin sekmeyi TabSet ayarlamak için ve koordinatlarına kendilerini ekler.
Tab.razor:
@using BlazorSample.UIInterfaces
@implements ITab
<li>
<a @onclick="ActivateTab" class="nav-link @TitleCssClass" role="button">
@Title
</a>
</li>
@code {
[CascadingParameter]
private 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);
}
}
Aşağıdaki ExampleTabSet bileşen, üç TabSet bileşen içeren bileşeni kullanırTab.
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;
}
Ek kaynaklar
ASP.NET Core