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, işleme sırasında öğe, bileşen ve model ilişkilerini korumak için yönerge özniteliğinin nasıl kullanılacağı ve öğeler veya bileşenler daha sonra değişirken nasıl kullanılacağı @key açıklanmaktadır.
Yönerge özniteliğinin @key kullanımı
Öğelerin veya bileşenlerin listesini oluştururken ve öğeler ya da bileşenler daha sonra değişirken, Blazor önceki öğelerden veya bileşenlerden hangisinin korunacaklarına ve model nesnelerinin bunlara nasıl eşlenmesi gerektiğine karar vermelidir. Normalde, bu işlem otomatiktir ve genel işleme için yeterlidir, ancak genellikle yönerge özniteliğini kullanarak işlemi denetlemenin @key gerekli olduğu durumlar vardır.
kullanılarak @keyçözülen bir koleksiyon eşleme sorununu gösteren aşağıdaki örneği göz önünde bulundurun.
Aşağıdaki bileşenler için:
- Bileşen
Details, birDataöğede görüntülenen üst bileşenden (<input>) veri alır. Kullanıcı<input>öğelerinden birini seçtiğinde, görüntülenen belirli<input>öğesi kullanıcıdan sayfanın odağını alabilir. - Üst bileşen, bileşeni kullanarak görüntülenecek kişi nesnelerinin
Detailslistesini oluşturur. Her üç saniyede bir koleksiyona yeni bir kişi eklenir.
Bu tanıtım şunları yapmanızı sağlar:
- İşlenmiş çeşitli
<input>bileşenleri arasından birDetailsseçin. - Kişi koleksiyonu otomatik olarak büyürken sayfanın odağının davranışını inceleyin.
Details.razor:
<input value="@Data" />
@code {
[Parameter]
public string? Data { get; set; }
}
<input value="@Data" />
@code {
[Parameter]
public string? Data { get; set; }
}
<input value="@Data" />
@code {
[Parameter]
public string? Data { get; set; }
}
<input value="@Data" />
@code {
[Parameter]
public string? Data { get; set; }
}
<input value="@Data" />
@code {
[Parameter]
public string Data { get; set; }
}
<input value="@Data" />
@code {
[Parameter]
public string Data { get; set; }
}
Aşağıdaki üst bileşende, bir kişi OnTimerCallback eklemenin her yinelemesi koleksiyonun tamamının yeniden oluşturulmasına neden olur Blazor . Sayfanın odağı öğelerinin <input> konumunda kaldığından, her kişi eklendiğinde odak kayar. Odağın kullanıcı tarafından seçilen öğenin dışına kaydırılması istenen bir davranış değildir. Aşağıdaki bileşenin hatalı davranışı gösterildikten sonra, kullanıcının deneyimini geliştirmek için @key yönerge özniteliği kullanılmıştır.
People.razor:
@page "/people"
@using System.Timers
@implements IDisposable
<PageTitle>People</PageTitle>
<h1>People Example</h1>
@foreach (var person in people)
{
<Details Data="@person.Data" />
}
@code {
private Timer timer = new Timer(3000);
public List<Person> people =
new()
{
{ new Person { Data = "Person 1" } },
{ new Person { Data = "Person 2" } },
{ new Person { Data = "Person 3" } }
};
protected override void OnInitialized()
{
timer.Elapsed += (sender, eventArgs) => OnTimerCallback();
timer.Start();
}
private void OnTimerCallback()
{
_ = InvokeAsync(() =>
{
people.Insert(0,
new Person
{
Data = $"INSERTED {DateTime.Now.ToString("hh:mm:ss tt")}"
});
StateHasChanged();
});
}
public void Dispose() => timer.Dispose();
public class Person
{
public string? Data { get; set; }
}
}
People.razor:
@page "/people"
@using System.Timers
@implements IDisposable
<PageTitle>People</PageTitle>
<h1>People Example</h1>
@foreach (var person in people)
{
<Details Data="@person.Data" />
}
@code {
private Timer timer = new Timer(3000);
public List<Person> people =
new()
{
{ new Person { Data = "Person 1" } },
{ new Person { Data = "Person 2" } },
{ new Person { Data = "Person 3" } }
};
protected override void OnInitialized()
{
timer.Elapsed += (sender, eventArgs) => OnTimerCallback();
timer.Start();
}
private void OnTimerCallback()
{
_ = InvokeAsync(() =>
{
people.Insert(0,
new Person
{
Data = $"INSERTED {DateTime.Now.ToString("hh:mm:ss tt")}"
});
StateHasChanged();
});
}
public void Dispose() => timer.Dispose();
public class Person
{
public string? Data { get; set; }
}
}
PeopleExample.razor:
@page "/people-example"
@using System.Timers
@implements IDisposable
@foreach (var person in people)
{
<Details Data="@person.Data" />
}
@code {
private Timer timer = new Timer(3000);
public List<Person> people =
new()
{
{ new Person { Data = "Person 1" } },
{ new Person { Data = "Person 2" } },
{ new Person { Data = "Person 3" } }
};
protected override void OnInitialized()
{
timer.Elapsed += (sender, eventArgs) => OnTimerCallback();
timer.Start();
}
private void OnTimerCallback()
{
_ = InvokeAsync(() =>
{
people.Insert(0,
new Person
{
Data = $"INSERTED {DateTime.Now.ToString("hh:mm:ss tt")}"
});
StateHasChanged();
});
}
public void Dispose() => timer.Dispose();
public class Person
{
public string? Data { get; set; }
}
}
PeopleExample.razor:
@page "/people-example"
@using System.Timers
@implements IDisposable
@foreach (var person in people)
{
<Details Data="@person.Data" />
}
@code {
private Timer timer = new Timer(3000);
public List<Person> people =
new()
{
{ new Person { Data = "Person 1" } },
{ new Person { Data = "Person 2" } },
{ new Person { Data = "Person 3" } }
};
protected override void OnInitialized()
{
timer.Elapsed += (sender, eventArgs) => OnTimerCallback();
timer.Start();
}
private void OnTimerCallback()
{
_ = InvokeAsync(() =>
{
people.Insert(0,
new Person
{
Data = $"INSERTED {DateTime.Now.ToString("hh:mm:ss tt")}"
});
StateHasChanged();
});
}
public void Dispose() => timer.Dispose();
public class Person
{
public string? Data { get; set; }
}
}
PeopleExample.razor:
@page "/people-example"
@using System.Timers
@implements IDisposable
@foreach (var person in people)
{
<Details Data="@person.Data" />
}
@code {
private Timer timer = new Timer(3000);
public List<Person> people =
new()
{
{ new Person { Data = "Person 1" } },
{ new Person { Data = "Person 2" } },
{ new Person { Data = "Person 3" } }
};
protected override void OnInitialized()
{
timer.Elapsed += (sender, eventArgs) => OnTimerCallback();
timer.Start();
}
private void OnTimerCallback()
{
_ = InvokeAsync(() =>
{
people.Insert(0,
new Person
{
Data = $"INSERTED {DateTime.Now.ToString("hh:mm:ss tt")}"
});
StateHasChanged();
});
}
public void Dispose() => timer.Dispose();
public class Person
{
public string Data { get; set; }
}
}
PeopleExample.razor:
@page "/people-example"
@using System.Timers
@implements IDisposable
@foreach (var person in people)
{
<Details Data="@person.Data" />
}
@code {
private Timer timer = new Timer(3000);
public List<Person> people =
new List<Person>()
{
{ new Person { Data = "Person 1" } },
{ new Person { Data = "Person 2" } },
{ new Person { Data = "Person 3" } }
};
protected override void OnInitialized()
{
timer.Elapsed += (sender, eventArgs) => OnTimerCallback();
timer.Start();
}
private void OnTimerCallback()
{
_ = InvokeAsync(() =>
{
people.Insert(0,
new Person
{
Data = $"INSERTED {DateTime.Now.ToString("hh:mm:ss tt")}"
});
StateHasChanged();
});
}
public void Dispose() => timer.Dispose();
public class Person
{
public string Data { get; set; }
}
}
people koleksiyonun içeriği eklenen, silinen veya yeniden sıralanan girdilerle değişir. Yeniden işleme, görünür davranış farklılıklarına yol açabilir. Örneğin, bir kişi koleksiyona people her eklendiğinde kullanıcının odağı kaybolur.
Öğeleri veya bileşenleri koleksiyona eşleme işlemi @key yönerge özniteliği ile denetlenebilir.
@key yönerge özniteliğinin kullanılması, anahtarın değerine dayanarak öğelerin veya bileşenlerin korunmasını garanti eder. Yukarıdaki örnekte yer alan Details bileşeninde person öğesine anahtar uygulanırsa, Blazor değişmemiş olan Details bileşenlerinin yeniden işlenmesini yoksayar.
Üst bileşeni, yönerge özniteliğini @key koleksiyonla people kullanacak şekilde değiştirmek için öğesini aşağıdaki şekilde güncelleştirin <Details> :
<Details @key="person" Data="@person.Data" />
people koleksiyonu değiştiğinde Details örnekleri ile person örnekleri arasındaki ilişki korunur. Koleksiyonun başlangıcına bir Person eklendiğinde, buna karşılık gelen konuma yeni bir Details örneği eklenir. Diğer örnekler olduğu gibi bırakılır. Bu nedenle koleksiyona kişiler eklendikçe kullanıcının odağı kaybolmaz.
@key yönerge özniteliği kullanıldığında diğer koleksiyon güncelleştirmeleri de aynı davranışı gösterir:
- Koleksiyondan örnek silindiğinde kullanıcı arabiriminden yalnızca silinen örneğe karşılık gelen bileşen örneği kaldırılır. Diğer örnekler olduğu gibi bırakılır.
- Koleksiyon girdileri yeniden sıralanır, kullanıcı arabiriminde bunlara karşılık gelen bileşen örnekleri korunur ve yeniden sıralanır.
Önemli
Anahtarlar her kapsayıcı öğesi veya bileşeni için yereldir. Anahtarlar belgede genel olarak karşılaştırılamaz.
@key ne zaman kullanılmalı?
Normalde her liste işlendiğinde (örneğin bir @key bloğunda) ve foreach yönerge özniteliğini tanımlayacak uygun bir değer olduğunda @key kullanmak mantıklıdır.
Ayrıca aşağıdaki örneklerde gösterildiği gibi, bir nesne değişmediğinde öğe veya bileşen alt ağacını korumak için de @key kullanabilirsiniz.
Örnek 1:
<li @key="person">
<input value="@person.Data" />
</li>
Örnek 2:
<div @key="person">
@* other HTML elements *@
</div>
Bir person örneği değiştiğinde @key öznitelik yönergesi Blazor'ı şunları yapmaya zorlar:
-
<li>ve<div>öğelerinin tamamını ve bunların alt öğelerini atma. - Kullanıcı arabirimi içinde yeni öğeler ve bileşenlerle alt ağacı yeniden oluşturma.
Alt ağaç içinde koleksiyon değiştiğinde hiçbir kullanıcı arabirimi durumunun korunmadığından emin olmak için bu yararlıdır.
@key kapsamı
@key öznitelik yönergesinin kapsamı, üst öğesi içindeki kendi eşdüzeyleri olarak belirlenir.
Aşağıdaki örneği inceleyin.
first ile second anahtarları, dış <div> öğesiyle aynı kapsam içinde birbiriyle karşılaştırılır:
<div>
<div @key="first">...</div>
<div @key="second">...</div>
</div>
Aşağıdaki örnek first ile second anahtarlarını kendi kapsamlarında, birbirleriyle ilişkisiz olarak ve birbirlerini etkilemeyecek şekilde gösterir. Her @key kapsamı yalnızca kendi üst <div> öğesine uygulanır; üst <div> öğeleri arasında uygulanmaz:
<div>
<div @key="first">...</div>
</div>
<div>
<div @key="second">...</div>
</div>
Daha önce gösterilen Details bileşeni için, aşağıdaki örnekler aynı person kapsamı içinde @key verilerini işler ve @key için tipik kullanım örneklerini gösterir:
<div>
@foreach (var person in people)
{
<Details @key="person" Data="@person.Data" />
}
</div>
@foreach (var person in people)
{
<div @key="person">
<Details Data="@person.Data" />
</div>
}
<ol>
@foreach (var person in people)
{
<li @key="person">
<Details Data="@person.Data" />
</li>
}
</ol>
Aşağıdaki örneklerde @key kapsamı yalnızca her <div> bileşen örneğini çevreleyen <li> veya Details öğesidir. Bu nedenle person koleksiyonunun her üyesinin people verilerine, işlenen bileşenleri genelindeki her person örneğinde anahtar Details.
@key kullanırken aşağıdaki desenlerden kaçının:
@foreach (var person in people)
{
<div>
<Details @key="person" Data="@person.Data" />
</div>
}
<ol>
@foreach (var person in people)
{
<li>
<Details @key="person" Data="@person.Data" />
</li>
}
</ol>
@key ne zaman kullanılmamalı?
@key ile işlemenin performans maliyeti vardır. Performans maliyeti yüksek değildir ama @key yönerge özniteliğini yalnızca öğeyi veya bileşeni korumanın uygulama açısından faydalı olacağı durumlarda belirtin.
@key kullanılmasa bile Blazor alt öğe ve bileşen örneklerini mümkün olduğunca korur.
@key kullanmanın tek avantajı, model örneklerinin korunan bileşen örneklerine nasıl eşleneceğini Blazor'ın seçmesi yerine bu eşleme üzerinde denetim sahibi olmaktır.
@key için kullanılacak değerler
Genellikle @key için aşağıdaki değerlerden birini sağlamak mantıklı olur:
- Model nesnesi örnekleri. Örneğin yukarıdaki örnekte
Personörneği (person) kullanılmıştı. Bu, nesne başvurusu eşitliği temelinde koruma sağlar. - Benzersiz tanımlayıcılar. Örneğin benzersiz tanımlayıcılar
int,stringveyaGuidtüründeki birincil anahtar değerlerini temel alabilir.
@key için kullanılan değerlerin çakışmadığından emin olun. Aynı üst öğede çakışan değerler algılanırsa, Blazor eski öğeleri veya bileşenleri belirleyici bir şekilde yeni öğelere veya bileşenlere eşleyemediğinden bir özel durum oluşturur. Yalnızca nesne örnekleri veya birincil anahtar değerleri gibi farklı değerler kullanın.
ASP.NET Core