Eventos
Campeonato Mundial de Visualização de Dados do Power BI
14 de fev., 16 - 31 de mar., 16
Com 4 chances de participar, você pode ganhar um pacote de conferência e chegar à Grande Final AO VIVO em Las Vegas
Saiba maisNão há mais suporte para esse navegador.
Atualize o Microsoft Edge para aproveitar os recursos, o suporte técnico e as atualizações de segurança mais recentes.
Observação
Esta não é a versão mais recente deste artigo. Para a versão atual, consulte a versão .NET 9 deste artigo.
Aviso
Esta versão do ASP.NET Core não tem mais suporte. Para obter mais informações, consulte a Política de Suporte do .NET e do .NET Core. Para a versão atual, consulte a versão .NET 9 deste artigo.
Importante
Essas informações relacionam-se ao produto de pré-lançamento, que poderá ser substancialmente modificado antes do lançamento comercial. A Microsoft não oferece nenhuma garantia, explícita ou implícita, quanto às informações fornecidas aqui.
Para a versão atual, consulte a versão .NET 9 deste artigo.
Por Robert Haken
Este artigo mostra como os componentes de modelo podem aceitar um ou mais modelos de interface do usuário como parâmetros, que podem ser usados como parte da lógica de renderização do componente.
Componentes modelo recebem um ou mais modelos de interface do usuário como parâmetros. Eles podem ser utilizados na lógica de renderização do componente. Usando componentes com modelo, você pode criar componentes de nível superior que são mais reutilizáveis. Os exemplos incluem:
Um componente modelo é definido especificando um ou mais parâmetros de componente do tipo RenderFragment ou RenderFragment<TValue>. Um fragmento de renderização representa um segmento da interface do usuário a ser renderizado. RenderFragment<TValue> usa um parâmetro de tipo que pode ser especificado quando o fragmento de renderização é invocado.
Observação
Para obter mais informações sobre RenderFragment, confira Componentes Razordo ASP.NET Core.
Geralmente, os componentes de modelo são tipificados genericamente, como demonstra o componente TemplatedNavBar
(TemplatedNavBar.razor
) a seguir. O tipo genérico (<T>
) no exemplo a seguir é usado para renderizar valores de IReadOnlyList<T>, que nesse caso é uma lista de animais de estimação para um componente que exibe uma barra de navegação com links para um componente de detalhes do animal de estimação.
TemplatedNavBar.razor
:
@typeparam TItem
<nav class="navbar navbar-expand navbar-light bg-light">
<div class="container justify-content-start">
@StartContent
<div class="navbar-nav">
@foreach (var item in Items)
{
@ItemTemplate(item)
}
</div>
</div>
</nav>
@code {
[Parameter]
public RenderFragment? StartContent { get; set; }
[Parameter, EditorRequired]
public RenderFragment<TItem> ItemTemplate { get; set; } = default!;
[Parameter, EditorRequired]
public IReadOnlyList<TItem> Items { get; set; } = default!;
}
@typeparam TItem
<nav class="navbar navbar-expand navbar-light bg-light">
<div class="container justify-content-start">
@StartContent
<div class="navbar-nav">
@foreach (var item in Items)
{
@ItemTemplate(item)
}
</div>
</div>
</nav>
@code {
[Parameter]
public RenderFragment? StartContent { get; set; }
[Parameter, EditorRequired]
public RenderFragment<TItem> ItemTemplate { get; set; } = default!;
[Parameter, EditorRequired]
public IReadOnlyList<TItem> Items { get; set; } = default!;
}
@typeparam TItem
<nav class="navbar navbar-expand navbar-light bg-light">
<div class="container justify-content-start">
@StartContent
<div class="navbar-nav">
@foreach (var item in Items)
{
@ItemTemplate(item)
}
</div>
</div>
</nav>
@code {
[Parameter]
public RenderFragment? StartContent { get; set; }
[Parameter, EditorRequired]
public RenderFragment<TItem> ItemTemplate { get; set; } = default!;
[Parameter, EditorRequired]
public IReadOnlyList<TItem> Items { get; set; } = default!;
}
@typeparam TItem
<nav class="navbar navbar-expand navbar-light bg-light">
<div class="container justify-content-start">
@StartContent
<div class="navbar-nav">
@foreach (var item in Items)
{
@ItemTemplate(item)
}
</div>
</div>
</nav>
@code {
[Parameter]
public RenderFragment? StartContent { get; set; }
[Parameter, EditorRequired]
public RenderFragment<TItem> ItemTemplate { get; set; } = default!;
[Parameter, EditorRequired]
public IReadOnlyList<TItem> Items { get; set; } = default!;
}
@typeparam TItem
<nav class="navbar navbar-expand navbar-light bg-light">
<div class="container justify-content-start">
@StartContent
<div class="navbar-nav">
@foreach (var item in Items)
{
@ItemTemplate(item)
}
</div>
</div>
</nav>
@code {
[Parameter]
public RenderFragment StartContent { get; set; }
[Parameter]
public RenderFragment<TItem> ItemTemplate { get; set; } = default;
[Parameter]
public IReadOnlyList<TItem> Items { get; set; } = default;
}
@typeparam TItem
<nav class="navbar navbar-expand navbar-light bg-light">
<div class="container justify-content-start">
@StartContent
<div class="navbar-nav">
@foreach (var item in Items)
{
@ItemTemplate(item)
}
</div>
</div>
</nav>
@code {
[Parameter]
public RenderFragment StartContent { get; set; }
[Parameter]
public RenderFragment<TItem> ItemTemplate { get; set; } = default;
[Parameter]
public IReadOnlyList<TItem> Items { get; set; } = default;
}
Ao usar um componente modelo, os parâmetros do modelo podem ser especificados usando elementos filho que correspondem aos nomes dos parâmetros. No exemplo a seguir, <StartContent>...</StartContent>
e <ItemTemplate>...</ItemTemplate>
fornecem modelos RenderFragment<TValue> para StartContent
e ItemTemplate
do componente TemplatedNavBar
.
Especifique o atributo Context
no elemento de componente quando quiser especificar o nome do parâmetro de conteúdo para conteúdo filho implícito (sem nenhum elemento filho de encapsulamento). No exemplo a seguir, o atributo Context
aparece no elemento TemplatedNavBar
e se aplica a todos os parâmetros de modelo RenderFragment<TValue>.
Pets1.razor
:
@page "/pets-1"
<PageTitle>Pets 1</PageTitle>
<h1>Pets Example 1</h1>
<TemplatedNavBar Items="pets" Context="pet">
<StartContent>
<a href="/" class="navbar-brand">PetsApp</a>
</StartContent>
<ItemTemplate>
<NavLink href="@($"/pet-detail/{pet.PetId}?ReturnUrl=%2Fpets-1")" class="nav-link">
@pet.Name
</NavLink>
</ItemTemplate>
</TemplatedNavBar>
@code {
private List<Pet> pets = new()
{
new Pet { PetId = 1, Name = "Mr. Bigglesworth" },
new Pet { PetId = 2, Name = "Salem Saberhagen" },
new Pet { PetId = 3, Name = "K-9" }
};
private class Pet
{
public int PetId { get; set; }
public string? Name { get; set; }
}
}
@page "/pets-1"
<PageTitle>Pets 1</PageTitle>
<h1>Pets Example 1</h1>
<TemplatedNavBar Items="pets" Context="pet">
<StartContent>
<a href="/" class="navbar-brand">PetsApp</a>
</StartContent>
<ItemTemplate>
<NavLink href="@($"/pet-detail/{pet.PetId}?ReturnUrl=%2Fpets-1")" class="nav-link">
@pet.Name
</NavLink>
</ItemTemplate>
</TemplatedNavBar>
@code {
private List<Pet> pets = new()
{
new Pet { PetId = 1, Name = "Mr. Bigglesworth" },
new Pet { PetId = 2, Name = "Salem Saberhagen" },
new Pet { PetId = 3, Name = "K-9" }
};
private class Pet
{
public int PetId { get; set; }
public string? Name { get; set; }
}
}
@page "/pets-1"
<PageTitle>Pets 1</PageTitle>
<h1>Pets Example 1</h1>
<TemplatedNavBar Items="pets" Context="pet">
<StartContent>
<a href="/" class="navbar-brand">PetsApp</a>
</StartContent>
<ItemTemplate>
<NavLink href="@($"/pet-detail/{pet.PetId}?ReturnUrl=%2Fpets-1")" class="nav-link">
@pet.Name
</NavLink>
</ItemTemplate>
</TemplatedNavBar>
@code {
private List<Pet> pets = new()
{
new Pet { PetId = 1, Name = "Mr. Bigglesworth" },
new Pet { PetId = 2, Name = "Salem Saberhagen" },
new Pet { PetId = 3, Name = "K-9" }
};
private class Pet
{
public int PetId { get; set; }
public string? Name { get; set; }
}
}
@page "/pets-1"
<PageTitle>Pets 1</PageTitle>
<h1>Pets Example 1</h1>
<TemplatedNavBar Items="pets" Context="pet">
<StartContent>
<a href="/" class="navbar-brand">PetsApp</a>
</StartContent>
<ItemTemplate>
<NavLink href="@($"/pet-detail/{pet.PetId}")" class="nav-link">
@pet.Name
</NavLink>
</ItemTemplate>
</TemplatedNavBar>
@code {
private List<Pet> pets = new()
{
new Pet { PetId = 1, Name = "Mr. Bigglesworth" },
new Pet { PetId = 2, Name = "Salem Saberhagen" },
new Pet { PetId = 3, Name = "K-9" }
};
private class Pet
{
public int PetId { get; set; }
public string? Name { get; set; }
}
}
@page "/pets-1"
<h1>Pets Example 1</h1>
<TemplatedNavBar Items="pets" Context="pet">
<StartContent>
<a href="/" class="navbar-brand">PetsApp</a>
</StartContent>
<ItemTemplate>
<NavLink href="@($"/pet-detail/{pet.PetId}")" class="nav-link">
@pet.Name
</NavLink>
</ItemTemplate>
</TemplatedNavBar>
@code {
private List<Pet> pets = new()
{
new Pet { PetId = 1, Name = "Mr. Bigglesworth" },
new Pet { PetId = 2, Name = "Salem Saberhagen" },
new Pet { PetId = 3, Name = "K-9" }
};
private class Pet
{
public int PetId { get; set; }
public string Name { get; set; }
}
}
@page "/pets-1"
<h1>Pets Example 1</h1>
<TemplatedNavBar Items="pets" Context="pet">
<StartContent>
<a href="/" class="navbar-brand">PetsApp</a>
</StartContent>
<ItemTemplate>
<NavLink href="@($"/pet-detail/{pet.PetId}")" class="nav-link">
@pet.Name
</NavLink>
</ItemTemplate>
</TemplatedNavBar>
@code {
private List<Pet> pets = new()
{
new Pet { PetId = 1, Name = "Mr. Bigglesworth" },
new Pet { PetId = 2, Name = "Salem Saberhagen" },
new Pet { PetId = 3, Name = "K-9" }
};
private class Pet
{
public int PetId { get; set; }
public string Name { get; set; }
}
}
Você pode alterar o nome desse parâmetro de implementação usando o atributo Context
no elemento filho RenderFragment<TValue>. No exemplo a seguir, o Context
é definido em ItemTemplate
em vez de TemplatedNavBar
.
Pets2.razor
:
@page "/pets-2"
<PageTitle>Pets 2</PageTitle>
<h1>Pets Example 2</h1>
<TemplatedNavBar Items="pets">
<StartContent>
<a href="/" class="navbar-brand">PetsApp</a>
</StartContent>
<ItemTemplate Context="pet">
<NavLink href="@($"/pet-detail/{pet.PetId}?ReturnUrl=%2Fpets-2")" class="nav-link">
@pet.Name
</NavLink>
</ItemTemplate>
</TemplatedNavBar>
@code {
private List<Pet> pets = new()
{
new Pet { PetId = 1, Name = "Mr. Bigglesworth" },
new Pet { PetId = 2, Name = "Salem Saberhagen" },
new Pet { PetId = 3, Name = "K-9" }
};
private class Pet
{
public int PetId { get; set; }
public string? Name { get; set; }
}
}
@page "/pets-2"
<PageTitle>Pets 2</PageTitle>
<h1>Pets Example 2</h1>
<TemplatedNavBar Items="pets">
<StartContent>
<a href="/" class="navbar-brand">PetsApp</a>
</StartContent>
<ItemTemplate Context="pet">
<NavLink href="@($"/pet-detail/{pet.PetId}?ReturnUrl=%2Fpets-2")" class="nav-link">
@pet.Name
</NavLink>
</ItemTemplate>
</TemplatedNavBar>
@code {
private List<Pet> pets = new()
{
new Pet { PetId = 1, Name = "Mr. Bigglesworth" },
new Pet { PetId = 2, Name = "Salem Saberhagen" },
new Pet { PetId = 3, Name = "K-9" }
};
private class Pet
{
public int PetId { get; set; }
public string? Name { get; set; }
}
}
@page "/pets-2"
<PageTitle>Pets 2</PageTitle>
<h1>Pets Example 2</h1>
<TemplatedNavBar Items="pets">
<StartContent>
<a href="/" class="navbar-brand">PetsApp</a>
</StartContent>
<ItemTemplate Context="pet">
<NavLink href="@($"/pet-detail/{pet.PetId}?ReturnUrl=%2Fpets-2")" class="nav-link">
@pet.Name
</NavLink>
</ItemTemplate>
</TemplatedNavBar>
@code {
private List<Pet> pets = new()
{
new Pet { PetId = 1, Name = "Mr. Bigglesworth" },
new Pet { PetId = 2, Name = "Salem Saberhagen" },
new Pet { PetId = 3, Name = "K-9" }
};
private class Pet
{
public int PetId { get; set; }
public string? Name { get; set; }
}
}
@page "/pets-2"
<PageTitle>Pets 2</PageTitle>
<h1>Pets Example 2</h1>
<TemplatedNavBar Items="pets">
<StartContent>
<a href="/" class="navbar-brand">PetsApp</a>
</StartContent>
<ItemTemplate Context="pet">
<NavLink href="@($"/pet-detail/{pet.PetId}")" class="nav-link">
@pet.Name
</NavLink>
</ItemTemplate>
</TemplatedNavBar>
@code {
private List<Pet> pets = new()
{
new Pet { PetId = 1, Name = "Mr. Bigglesworth" },
new Pet { PetId = 2, Name = "Salem Saberhagen" },
new Pet { PetId = 3, Name = "K-9" }
};
private class Pet
{
public int PetId { get; set; }
public string? Name { get; set; }
}
}
@page "/pets-2"
<h1>Pets Example 2</h1>
<TemplatedNavBar Items="pets">
<StartContent>
<a href="/" class="navbar-brand">PetsApp</a>
</StartContent>
<ItemTemplate Context="pet">
<NavLink href="@($"/pet-detail/{pet.PetId}")" class="nav-link">
@pet.Name
</NavLink>
</ItemTemplate>
</TemplatedNavBar>
@code {
private List<Pet> pets = new()
{
new Pet { PetId = 1, Name = "Mr. Bigglesworth" },
new Pet { PetId = 2, Name = "Salem Saberhagen" },
new Pet { PetId = 3, Name = "K-9" }
};
private class Pet
{
public int PetId { get; set; }
public string Name { get; set; }
}
}
@page "/pets-2"
<h1>Pets Example 2</h1>
<TemplatedNavBar Items="pets">
<StartContent>
<a href="/" class="navbar-brand">PetsApp</a>
</StartContent>
<ItemTemplate Context="pet">
<NavLink href="@($"/pet-detail/{pet.PetId}")" class="nav-link">
@pet.Name
</NavLink>
</ItemTemplate>
</TemplatedNavBar>
@code {
private List<Pet> pets = new()
{
new Pet { PetId = 1, Name = "Mr. Bigglesworth" },
new Pet { PetId = 2, Name = "Salem Saberhagen" },
new Pet { PetId = 3, Name = "K-9" }
};
private class Pet
{
public int PetId { get; set; }
public string Name { get; set; }
}
}
Os argumentos de componente do tipo RenderFragment<TValue> têm um parâmetro implícito denominado context
, que pode ser usado. No exemplo a seguir, Context
não está definido. @context.{PROPERTY}
fornece valores de animais de estimação para o modelo, em que {PROPERTY}
é uma propriedade Pet
:
Pets3.razor
:
@page "/pets-3"
<PageTitle>Pets 3</PageTitle>
<h1>Pets Example 3</h1>
<TemplatedNavBar Items="pets">
<StartContent>
<a href="/" class="navbar-brand">PetsApp</a>
</StartContent>
<ItemTemplate>
<NavLink href="@($"/pet-detail/{context.PetId}?ReturnUrl=%2Fpets-3")" class="nav-link">
@context.Name
</NavLink>
</ItemTemplate>
</TemplatedNavBar>
@code {
private List<Pet> pets = new()
{
new Pet { PetId = 1, Name = "Mr. Bigglesworth" },
new Pet { PetId = 2, Name = "Salem Saberhagen" },
new Pet { PetId = 3, Name = "K-9" }
};
private class Pet
{
public int PetId { get; set; }
public string? Name { get; set; }
}
}
@page "/pets-3"
<PageTitle>Pets 3</PageTitle>
<h1>Pets Example 3</h1>
<TemplatedNavBar Items="pets">
<StartContent>
<a href="/" class="navbar-brand">PetsApp</a>
</StartContent>
<ItemTemplate>
<NavLink href="@($"/pet-detail/{context.PetId}?ReturnUrl=%2Fpets-3")" class="nav-link">
@context.Name
</NavLink>
</ItemTemplate>
</TemplatedNavBar>
@code {
private List<Pet> pets = new()
{
new Pet { PetId = 1, Name = "Mr. Bigglesworth" },
new Pet { PetId = 2, Name = "Salem Saberhagen" },
new Pet { PetId = 3, Name = "K-9" }
};
private class Pet
{
public int PetId { get; set; }
public string? Name { get; set; }
}
}
@page "/pets-3"
<PageTitle>Pets 3</PageTitle>
<h1>Pets Example 3</h1>
<TemplatedNavBar Items="pets">
<StartContent>
<a href="/" class="navbar-brand">PetsApp</a>
</StartContent>
<ItemTemplate>
<NavLink href="@($"/pet-detail/{context.PetId}?ReturnUrl=%2Fpets-3")" class="nav-link">
@context.Name
</NavLink>
</ItemTemplate>
</TemplatedNavBar>
@code {
private List<Pet> pets = new()
{
new Pet { PetId = 1, Name = "Mr. Bigglesworth" },
new Pet { PetId = 2, Name = "Salem Saberhagen" },
new Pet { PetId = 3, Name = "K-9" }
};
private class Pet
{
public int PetId { get; set; }
public string? Name { get; set; }
}
}
@page "/pets-3"
<PageTitle>Pets 3</PageTitle>
<h1>Pets Example 3</h1>
<TemplatedNavBar Items="pets">
<StartContent>
<a href="/" class="navbar-brand">PetsApp</a>
</StartContent>
<ItemTemplate>
<NavLink href="@($"/pet-detail/{context.PetId}")" class="nav-link">
@context.Name
</NavLink>
</ItemTemplate>
</TemplatedNavBar>
@code {
private List<Pet> pets = new()
{
new Pet { PetId = 1, Name = "Mr. Bigglesworth" },
new Pet { PetId = 2, Name = "Salem Saberhagen" },
new Pet { PetId = 3, Name = "K-9" }
};
private class Pet
{
public int PetId { get; set; }
public string? Name { get; set; }
}
}
@page "/pets-3"
<h1>Pets Example 3</h1>
<TemplatedNavBar Items="pets">
<StartContent>
<a href="/" class="navbar-brand">PetsApp</a>
</StartContent>
<ItemTemplate>
<NavLink href="@($"/pet-detail/{context.PetId}")" class="nav-link">
@context.Name
</NavLink>
</ItemTemplate>
</TemplatedNavBar>
@code {
private List<Pet> pets = new()
{
new Pet { PetId = 1, Name = "Mr. Bigglesworth" },
new Pet { PetId = 2, Name = "Salem Saberhagen" },
new Pet { PetId = 3, Name = "K-9" }
};
private class Pet
{
public int PetId { get; set; }
public string Name { get; set; }
}
}
@page "/pets-3"
<h1>Pets Example 3</h1>
<TemplatedNavBar Items="pets">
<StartContent>
<a href="/" class="navbar-brand">PetsApp</a>
</StartContent>
<ItemTemplate>
<NavLink href="@($"/pet-detail/{context.PetId}")" class="nav-link">
@context.Name
</NavLink>
</ItemTemplate>
</TemplatedNavBar>
@code {
private List<Pet> pets = new()
{
new Pet { PetId = 1, Name = "Mr. Bigglesworth" },
new Pet { PetId = 2, Name = "Salem Saberhagen" },
new Pet { PetId = 3, Name = "K-9" }
};
private class Pet
{
public int PetId { get; set; }
public string Name { get; set; }
}
}
Ao usar componentes de tipo genérico, o parâmetro de tipo é inferido, se possível. No entanto, é possível especificar explicitamente o tipo com um atributo que tem um nome que corresponda ao parâmetro de tipo, que está TItem
no exemplo anterior:
Pets4.razor
:
@page "/pets-4"
<PageTitle>Pets 4</PageTitle>
<h1>Pets Example 4</h1>
<TemplatedNavBar Items="pets" Context="pet" TItem="Pet">
<StartContent>
<a href="/" class="navbar-brand">PetsApp</a>
</StartContent>
<ItemTemplate>
<NavLink href="@($"/pet-detail/{pet.PetId}?ReturnUrl=%2Fpets-4")" class="nav-link">
@pet.Name
</NavLink>
</ItemTemplate>
</TemplatedNavBar>
@code {
private List<Pet> pets = new()
{
new Pet { PetId = 2, Name = "Mr. Bigglesworth" },
new Pet { PetId = 4, Name = "Salem Saberhagen" },
new Pet { PetId = 7, Name = "K-9" }
};
private class Pet
{
public int PetId { get; set; }
public string? Name { get; set; }
}
}
@page "/pets-4"
<PageTitle>Pets 4</PageTitle>
<h1>Pets Example 4</h1>
<TemplatedNavBar Items="pets" Context="pet" TItem="Pet">
<StartContent>
<a href="/" class="navbar-brand">PetsApp</a>
</StartContent>
<ItemTemplate>
<NavLink href="@($"/pet-detail/{pet.PetId}?ReturnUrl=%2Fpets-4")" class="nav-link">
@pet.Name
</NavLink>
</ItemTemplate>
</TemplatedNavBar>
@code {
private List<Pet> pets = new()
{
new Pet { PetId = 2, Name = "Mr. Bigglesworth" },
new Pet { PetId = 4, Name = "Salem Saberhagen" },
new Pet { PetId = 7, Name = "K-9" }
};
private class Pet
{
public int PetId { get; set; }
public string? Name { get; set; }
}
}
@page "/pets-4"
<PageTitle>Pets 4</PageTitle>
<h1>Pets Example 4</h1>
<TemplatedNavBar Items="pets" Context="pet" TItem="Pet">
<StartContent>
<a href="/" class="navbar-brand">PetsApp</a>
</StartContent>
<ItemTemplate>
<NavLink href="@($"/pet-detail/{pet.PetId}?ReturnUrl=%2Fpets-4")" class="nav-link">
@pet.Name
</NavLink>
</ItemTemplate>
</TemplatedNavBar>
@code {
private List<Pet> pets = new()
{
new Pet { PetId = 2, Name = "Mr. Bigglesworth" },
new Pet { PetId = 4, Name = "Salem Saberhagen" },
new Pet { PetId = 7, Name = "K-9" }
};
private class Pet
{
public int PetId { get; set; }
public string? Name { get; set; }
}
}
@page "/pets-4"
<PageTitle>Pets 4</PageTitle>
<h1>Pets Example 4</h1>
<TemplatedNavBar Items="pets" Context="pet" TItem="Pet">
<StartContent>
<a href="/" class="navbar-brand">PetsApp</a>
</StartContent>
<ItemTemplate>
<NavLink href="@($"/pet-detail/{pet.PetId}")" class="nav-link">
@pet.Name
</NavLink>
</ItemTemplate>
</TemplatedNavBar>
@code {
private List<Pet> pets = new()
{
new Pet { PetId = 2, Name = "Mr. Bigglesworth" },
new Pet { PetId = 4, Name = "Salem Saberhagen" },
new Pet { PetId = 7, Name = "K-9" }
};
private class Pet
{
public int PetId { get; set; }
public string? Name { get; set; }
}
}
@page "/pets-4"
<h1>Pets Example 4</h1>
<TemplatedNavBar Items="pets" Context="pet" TItem="Pet">
<StartContent>
<a href="/" class="navbar-brand">PetsApp</a>
</StartContent>
<ItemTemplate>
<NavLink href="@($"/pet-detail/{pet.PetId}")" class="nav-link">
@pet.Name
</NavLink>
</ItemTemplate>
</TemplatedNavBar>
@code {
private List<Pet> pets = new()
{
new Pet { PetId = 2, Name = "Mr. Bigglesworth" },
new Pet { PetId = 4, Name = "Salem Saberhagen" },
new Pet { PetId = 7, Name = "K-9" }
};
private class Pet
{
public int PetId { get; set; }
public string Name { get; set; }
}
}
@page "/pets-4"
<h1>Pets Example 4</h1>
<TemplatedNavBar Items="pets" Context="pet" TItem="Pet">
<StartContent>
<a href="/" class="navbar-brand">PetsApp</a>
</StartContent>
<ItemTemplate>
<NavLink href="@($"/pet-detail/{pet.PetId}")" class="nav-link">
@pet.Name
</NavLink>
</ItemTemplate>
</TemplatedNavBar>
@code {
private List<Pet> pets = new()
{
new Pet { PetId = 2, Name = "Mr. Bigglesworth" },
new Pet { PetId = 4, Name = "Salem Saberhagen" },
new Pet { PetId = 7, Name = "K-9" }
};
private class Pet
{
public int PetId { get; set; }
public string Name { get; set; }
}
}
O exemplo fornecido no componente TemplatedNavBar
(TemplatedNavBar.razor
) pressupõe que a coleção Items
não é alterada após a renderização inicial; ou que, se ele mudar, não será necessário manter o estado dos componentes/elementos usados no ItemTemplate
. Para componentes com modelos em que esse uso não pode ser antecipado, consulte a seção Preservar relações com @key
.
Componentes com modelo geralmente são usados para renderizar coleções de itens, como tabelas ou listas. Nesses cenários gerais, não podemos supor que o usuário evitará componentes/elementos com estado na definição do modelo de item ou que não haverá alterações adicionais na coleção Items
. Para esses componentes com modelo, é necessário preservar as relações com o atributo de diretiva @key
.
Observação
Para obter mais informações no atributo de diretiva @key
, confira Retenção de relações de elementos, componentes e modelos no ASP.NET Core Blazor.
O componente TableTemplate
(TableTemplate.razor
) a seguir demonstra um componente com modelo que preserva relações com @key
.
TableTemplate.razor
:
@typeparam TItem
<table class="table">
<thead>
<tr>@TableHeader</tr>
</thead>
<tbody>
@foreach (var item in Items)
{
<tr @key="@item">@RowTemplate(item)</tr>
}
</tbody>
</table>
@code {
[Parameter]
public RenderFragment? TableHeader { get; set; }
[Parameter, EditorRequired]
public RenderFragment<TItem> RowTemplate { get; set; } = default!;
[Parameter, EditorRequired]
public IReadOnlyList<TItem> Items { get; set; } = default!;
}
@typeparam TItem
<table class="table">
<thead>
<tr>@TableHeader</tr>
</thead>
<tbody>
@foreach (var item in Items)
{
<tr @key="@item">@RowTemplate(item)</tr>
}
</tbody>
</table>
@code {
[Parameter]
public RenderFragment? TableHeader { get; set; }
[Parameter, EditorRequired]
public RenderFragment<TItem> RowTemplate { get; set; } = default!;
[Parameter, EditorRequired]
public IReadOnlyList<TItem> Items { get; set; } = default!;
}
@typeparam TItem
<table class="table">
<thead>
<tr>@TableHeader</tr>
</thead>
<tbody>
@foreach (var item in Items)
{
<tr @key="@item">@RowTemplate(item)</tr>
}
</tbody>
</table>
@code {
[Parameter]
public RenderFragment? TableHeader { get; set; }
[Parameter, EditorRequired]
public RenderFragment<TItem> RowTemplate { get; set; } = default!;
[Parameter, EditorRequired]
public IReadOnlyList<TItem> Items { get; set; } = default!;
}
@typeparam TItem
<table class="table">
<thead>
<tr>@TableHeader</tr>
</thead>
<tbody>
@foreach (var item in Items)
{
<tr @key="@item">@RowTemplate(item)</tr>
}
</tbody>
</table>
@code {
[Parameter]
public RenderFragment? TableHeader { get; set; }
[Parameter, EditorRequired]
public RenderFragment<TItem> RowTemplate { get; set; } = default!;
[Parameter, EditorRequired]
public IReadOnlyList<TItem> Items { get; set; } = default!;
}
@typeparam TItem
<table class="table">
<thead>
<tr>@TableHeader</tr>
</thead>
<tbody>
@foreach (var item in Items)
{
<tr @key="@item">@RowTemplate(item)</tr>
}
</tbody>
</table>
@code {
[Parameter]
public RenderFragment TableHeader { get; set; }
[Parameter]
public RenderFragment<TItem> RowTemplate { get; set; } = default;
[Parameter]
public IReadOnlyList<TItem> Items { get; set; } = default;
}
@typeparam TItem
<table class="table">
<thead>
<tr>@TableHeader</tr>
</thead>
<tbody>
@foreach (var item in Items)
{
<tr @key="@item">@RowTemplate(item)</tr>
}
</tbody>
</table>
@code {
[Parameter]
public RenderFragment TableHeader { get; set; }
[Parameter]
public RenderFragment<TItem> RowTemplate { get; set; } = default;
[Parameter]
public IReadOnlyList<TItem> Items { get; set; } = default;
}
Considere o seguinte componente Pets5
(Pets5.razor
), que demonstra a importância de chavear dados para preservar relações de modelo. No componente, cada iteração de adicionar um animal de estimação em OnAfterRenderAsync
resulta no Blazor renderizar novamente o componente TableTemplate
.
Pets5.razor
:
@page "/pets-5"
<PageTitle>Pets 5</PageTitle>
<h1>Pets Example 5</h1>
<TableTemplate Items="pets" Context="pet">
<TableHeader>
<th>ID</th>
<th>Name</th>
</TableHeader>
<RowTemplate>
<td><input value="@pet.PetId" /></td>
<td><input value="@pet.Name" /></td>
</RowTemplate>
</TableTemplate>
@code {
private List<Pet> pets = new()
{
new Pet { PetId = 1, Name = "Mr. Bigglesworth" },
new Pet { PetId = 2, Name = "Salem Saberhagen" },
new Pet { PetId = 3, Name = "K-9" }
};
protected override async Task OnAfterRenderAsync(bool firstRender)
{
// Insert new pet every 5 seconds
if (pets.Count < 10)
{
await Task.Delay(5000);
pets.Insert(0, new Pet() { PetId = pets.Count + 1, Name = "<new pet>" });
StateHasChanged();
}
}
private class Pet
{
public int PetId { get; set; }
public string? Name { get; set; }
}
}
@page "/pets-5"
<PageTitle>Pets 5</PageTitle>
<h1>Pets Example 5</h1>
<TableTemplate Items="pets" Context="pet">
<TableHeader>
<th>ID</th>
<th>Name</th>
</TableHeader>
<RowTemplate>
<td><input value="@pet.PetId" /></td>
<td><input value="@pet.Name" /></td>
</RowTemplate>
</TableTemplate>
@code {
private List<Pet> pets = new()
{
new Pet { PetId = 1, Name = "Mr. Bigglesworth" },
new Pet { PetId = 2, Name = "Salem Saberhagen" },
new Pet { PetId = 3, Name = "K-9" }
};
protected override async Task OnAfterRenderAsync(bool firstRender)
{
// Insert new pet every 5 seconds
if (pets.Count < 10)
{
await Task.Delay(5000);
pets.Insert(0, new Pet() { PetId = pets.Count + 1, Name = "<new pet>" });
StateHasChanged();
}
}
private class Pet
{
public int PetId { get; set; }
public string? Name { get; set; }
}
}
@page "/pets-5"
<PageTitle>Pets 5</PageTitle>
<h1>Pets Example 5</h1>
<TableTemplate Items="pets" Context="pet">
<TableHeader>
<th>ID</th>
<th>Name</th>
</TableHeader>
<RowTemplate>
<td><input value="@pet.PetId" /></td>
<td><input value="@pet.Name" /></td>
</RowTemplate>
</TableTemplate>
@code {
private List<Pet> pets = new()
{
new Pet { PetId = 1, Name = "Mr. Bigglesworth" },
new Pet { PetId = 2, Name = "Salem Saberhagen" },
new Pet { PetId = 3, Name = "K-9" }
};
protected override async Task OnAfterRenderAsync(bool firstRender)
{
// Insert new pet every 5 seconds
if (pets.Count < 10)
{
await Task.Delay(5000);
pets.Insert(0, new Pet() { PetId = pets.Count + 1, Name = "<new pet>" });
StateHasChanged();
}
}
private class Pet
{
public int PetId { get; set; }
public string? Name { get; set; }
}
}
@page "/pets-5"
<PageTitle>Pets 5</PageTitle>
<h1>Pets Example 5</h1>
<TableTemplate Items="pets" Context="pet">
<TableHeader>
<th>ID</th>
<th>Name</th>
</TableHeader>
<RowTemplate>
<td><input value="@pet.PetId" /></td>
<td><input value="@pet.Name" /></td>
</RowTemplate>
</TableTemplate>
@code {
private List<Pet> pets = new()
{
new Pet { PetId = 1, Name = "Mr. Bigglesworth" },
new Pet { PetId = 2, Name = "Salem Saberhagen" },
new Pet { PetId = 3, Name = "K-9" }
};
protected override async Task OnAfterRenderAsync(bool firstRender)
{
// Insert new pet every 5 seconds
if (pets.Count < 10)
{
await Task.Delay(5000);
pets.Insert(0, new Pet() { PetId = pets.Count + 1, Name = "<new pet>" });
StateHasChanged();
}
}
private class Pet
{
public int PetId { get; set; }
public string? Name { get; set; }
}
}
@page "/pets-5"
<h1>Pets Example 5</h1>
<TableTemplate Items="pets" Context="pet">
<TableHeader>
<th>ID</th>
<th>Name</th>
</TableHeader>
<RowTemplate>
<td><input value="@pet.PetId" /></td>
<td><input value="@pet.Name" /></td>
</RowTemplate>
</TableTemplate>
@code {
private List<Pet> pets = new()
{
new Pet { PetId = 1, Name = "Mr. Bigglesworth" },
new Pet { PetId = 2, Name = "Salem Saberhagen" },
new Pet { PetId = 3, Name = "K-9" }
};
protected override async Task OnAfterRenderAsync(bool firstRender)
{
// Insert new pet every 5 seconds
if (pets.Count < 10)
{
await Task.Delay(5000);
pets.Insert(0, new Pet() { PetId = pets.Count + 1, Name = "<new pet>" });
StateHasChanged();
}
}
private class Pet
{
public int PetId { get; set; }
public string Name { get; set; }
}
}
@page "/pets-5"
<h1>Pets Example 5</h1>
<TableTemplate Items="pets" Context="pet">
<TableHeader>
<th>ID</th>
<th>Name</th>
</TableHeader>
<RowTemplate>
<td><input value="@pet.PetId" /></td>
<td><input value="@pet.Name" /></td>
</RowTemplate>
</TableTemplate>
@code {
private List<Pet> pets = new()
{
new Pet { PetId = 1, Name = "Mr. Bigglesworth" },
new Pet { PetId = 2, Name = "Salem Saberhagen" },
new Pet { PetId = 3, Name = "K-9" }
};
protected override async Task OnAfterRenderAsync(bool firstRender)
{
// Insert new pet every 5 seconds
if (pets.Count < 10)
{
await Task.Delay(5000);
pets.Insert(0, new Pet() { PetId = pets.Count + 1, Name = "<new pet>" });
StateHasChanged();
}
}
private class Pet
{
public int PetId { get; set; }
public string Name { get; set; }
}
}
Essa demonstração permite:
<input>
entre várias linhas de tabela renderizadas.Sem usar o atributo de diretiva @key
no componente TableTemplate
, o foco da página permanece na mesma posição de índice (linha) da tabela, fazendo com que o foco mude sempre que um animal de estimação é adicionado. Para demonstrar isso, remova o atributo e o valor da diretiva @key
, reinicie o aplicativo e tente modificar um valor de campo à medida que os itens são adicionados.
Comentários do ASP.NET Core
O ASP.NET Core é um projeto código aberto. Selecione um link para fornecer comentários:
Eventos
Campeonato Mundial de Visualização de Dados do Power BI
14 de fev., 16 - 31 de mar., 16
Com 4 chances de participar, você pode ganhar um pacote de conferência e chegar à Grande Final AO VIVO em Las Vegas
Saiba maisTreinamento
Módulo
Criar componentes interativos com aplicativos Web Blazor - Training
Aprenda a interoperar aplicativos Blazor com código JavaScript, usar componentes com modelo e lidar com eventos de ciclo de vida do componente.