Componentes com modelo Blazor no ASP.NET Core

Este artigo explica como os componentes 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 são componentes que aceitam 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. Os componentes modelo permitem criar componentes de nível superior que são mais reutilizáveis do que os componentes regulares. Alguns exemplos incluem:

  • Um componente de tabela que permite que um usuário especifique modelos para o cabeçalho, linhas e rodapé da tabela.
  • Um componente de lista que permite que um usuário especifique um modelo para renderizar itens em uma lista.

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, consulte ASP.NET Core Razor componentes.

Geralmente, os componentes modelo são tipado genericamente, como demonstra o componente a seguir TableTemplate . O tipo <T> genérico neste exemplo é usado para renderizar IReadOnlyList<T> valores, que nesse caso é uma série de linhas de animais de estimação em um componente que exibe uma tabela de animais de estimação.

Shared/TableTemplate.razor:

@typeparam TItem
@using System.Diagnostics.CodeAnalysis

<table class="table">
    <thead>
        <tr>@TableHeader</tr>
    </thead>
    <tbody>
        @foreach (var item in Items)
        {
            if (RowTemplate is not null)
            {
                <tr>@RowTemplate(item)</tr>
            }
        }
    </tbody>
</table>

@code {
    [Parameter]
    public RenderFragment? TableHeader { get; set; }

    [Parameter]
    public RenderFragment<TItem>? RowTemplate { get; set; }

    [Parameter, AllowNull]
    public IReadOnlyList<TItem> Items { get; set; }
}

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, <TableHeader>...</TableHeader> e <RowTemplate>...<RowTemplate> forneça RenderFragment<TValue> modelos para TableHeader e RowTemplate do TableTemplate componente.

Especifique o Context atributo 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 Context atributo aparece no TableTemplate elemento e se aplica a todos os RenderFragment<TValue> parâmetros de modelo.

Pages/Pets1.razor:

@page "/pets1"

<h1>Pets</h1>

<TableTemplate Items="pets" Context="pet">
    <TableHeader>
        <th>ID</th>
        <th>Name</th>
    </TableHeader>
    <RowTemplate>
        <td>@pet.PetId</td>
        <td>@pet.Name</td>
    </RowTemplate>
</TableTemplate>

@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; }
    }
}

Como alternativa, você pode alterar o nome do parâmetro usando o Context atributo no RenderFragment<TValue> elemento filho. No exemplo a seguir, o Context é definido em RowTemplate em vez de TableTemplate:

Pages/Pets2.razor:

@page "/pets2"

<h1>Pets</h1>

<TableTemplate Items="pets">
    <TableHeader>
        <th>ID</th>
        <th>Name</th>
    </TableHeader>
    <RowTemplate Context="pet">
        <td>@pet.PetId</td>
        <td>@pet.Name</td>
    </RowTemplate>
</TableTemplate>

@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; }
    }
}

Os argumentos de componente do tipo RenderFragment<TValue> têm um parâmetro implícito chamado 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 Pet propriedade:

Pages/Pets3.razor:

@page "/pets3"

<h1>Pets</h1>

<TableTemplate Items="pets">
    <TableHeader>
        <th>ID</th>
        <th>Name</th>
    </TableHeader>
    <RowTemplate>
        <td>@context.PetId</td>
        <td>@context.Name</td>
    </RowTemplate>
</TableTemplate>

@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; }
    }
}

Ao usar componentes de tipo genérico, o parâmetro de tipo é inferido, se possível. No entanto, você pode especificar explicitamente o tipo com um atributo que tem um nome que corresponda ao parâmetro de tipo, que está TItem no exemplo anterior:

Pages/Pets4.razor:

@page "/pets4"

<h1>Pets</h1>

<TableTemplate Items="pets" TItem="Pet">
    <TableHeader>
        <th>ID</th>
        <th>Name</th>
    </TableHeader>
    <RowTemplate>
        <td>@context.PetId</td>
        <td>@context.Name</td>
    </RowTemplate>
</TableTemplate>

@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; }
    }
}

Recursos adicionais

Componentes modelo são componentes que aceitam 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. Os componentes modelo permitem criar componentes de nível superior que são mais reutilizáveis do que os componentes regulares. Alguns exemplos incluem:

  • Um componente de tabela que permite que um usuário especifique modelos para o cabeçalho, linhas e rodapé da tabela.
  • Um componente de lista que permite que um usuário especifique um modelo para renderizar itens em uma lista.

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, consulte ASP.NET Core Razor componentes.

Geralmente, os componentes modelo são tipado genericamente, como demonstra o componente a seguir TableTemplate . O tipo <T> genérico neste exemplo é usado para renderizar IReadOnlyList<T> valores, que nesse caso é uma série de linhas de animais de estimação em um componente que exibe uma tabela de animais de estimação.

Shared/TableTemplate.razor:

@typeparam TItem
@using System.Diagnostics.CodeAnalysis

<table class="table">
    <thead>
        <tr>@TableHeader</tr>
    </thead>
    <tbody>
        @foreach (var item in Items)
        {
            if (RowTemplate is not null)
            {
                <tr>@RowTemplate(item)</tr>
            }
        }
    </tbody>
</table>

@code {
    [Parameter]
    public RenderFragment? TableHeader { get; set; }

    [Parameter]
    public RenderFragment<TItem>? RowTemplate { get; set; }

    [Parameter, AllowNull]
    public IReadOnlyList<TItem> Items { get; set; }
}

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, <TableHeader>...</TableHeader> e <RowTemplate>...<RowTemplate> forneça RenderFragment<TValue> modelos para TableHeader e RowTemplate do TableTemplate componente.

Especifique o Context atributo 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 Context atributo aparece no TableTemplate elemento e se aplica a todos os RenderFragment<TValue> parâmetros de modelo.

Pages/Pets1.razor:

@page "/pets1"

<h1>Pets</h1>

<TableTemplate Items="pets" Context="pet">
    <TableHeader>
        <th>ID</th>
        <th>Name</th>
    </TableHeader>
    <RowTemplate>
        <td>@pet.PetId</td>
        <td>@pet.Name</td>
    </RowTemplate>
</TableTemplate>

@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; }
    }
}

Como alternativa, você pode alterar o nome do parâmetro usando o Context atributo no RenderFragment<TValue> elemento filho. No exemplo a seguir, o Context é definido em RowTemplate em vez de TableTemplate:

Pages/Pets2.razor:

@page "/pets2"

<h1>Pets</h1>

<TableTemplate Items="pets">
    <TableHeader>
        <th>ID</th>
        <th>Name</th>
    </TableHeader>
    <RowTemplate Context="pet">
        <td>@pet.PetId</td>
        <td>@pet.Name</td>
    </RowTemplate>
</TableTemplate>

@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; }
    }
}

Os argumentos de componente do tipo RenderFragment<TValue> têm um parâmetro implícito chamado 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 Pet propriedade:

Pages/Pets3.razor:

@page "/pets3"

<h1>Pets</h1>

<TableTemplate Items="pets">
    <TableHeader>
        <th>ID</th>
        <th>Name</th>
    </TableHeader>
    <RowTemplate>
        <td>@context.PetId</td>
        <td>@context.Name</td>
    </RowTemplate>
</TableTemplate>

@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; }
    }
}

Ao usar componentes de tipo genérico, o parâmetro de tipo é inferido, se possível. No entanto, você pode especificar explicitamente o tipo com um atributo que tem um nome que corresponda ao parâmetro de tipo, que está TItem no exemplo anterior:

Pages/Pets4.razor:

@page "/pets4"

<h1>Pets</h1>

<TableTemplate Items="pets" TItem="Pet">
    <TableHeader>
        <th>ID</th>
        <th>Name</th>
    </TableHeader>
    <RowTemplate>
        <td>@context.PetId</td>
        <td>@context.Name</td>
    </RowTemplate>
</TableTemplate>

@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; }
    }
}

Recursos adicionais

Componentes modelo são componentes que aceitam 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. Os componentes modelo permitem criar componentes de nível superior que são mais reutilizáveis do que os componentes regulares. Alguns exemplos incluem:

  • Um componente de tabela que permite que um usuário especifique modelos para o cabeçalho, linhas e rodapé da tabela.
  • Um componente de lista que permite que um usuário especifique um modelo para renderizar itens em uma lista.

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, consulte ASP.NET Core Razor componentes.

Geralmente, os componentes modelo são tipado genericamente, como demonstra o componente a seguir TableTemplate . O tipo <T> genérico neste exemplo é usado para renderizar IReadOnlyList<T> valores, que nesse caso é uma série de linhas de animais de estimação em um componente que exibe uma tabela de animais de estimação.

Shared/TableTemplate.razor:

@typeparam TItem

<table class="table">
    <thead>
        <tr>@TableHeader</tr>
    </thead>
    <tbody>
        @foreach (var item in Items)
        {
            <tr>@RowTemplate(item)</tr>
        }
    </tbody>
</table>

@code {
    [Parameter]
    public RenderFragment TableHeader { get; set; }

    [Parameter]
    public RenderFragment<TItem> RowTemplate { get; set; }

    [Parameter]
    public IReadOnlyList<TItem> Items { get; set; }
}

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, <TableHeader>...</TableHeader> e <RowTemplate>...<RowTemplate> forneça RenderFragment<TValue> modelos para TableHeader e RowTemplate do TableTemplate componente.

Especifique o Context atributo 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 Context atributo aparece no TableTemplate elemento e se aplica a todos os RenderFragment<TValue> parâmetros de modelo.

Pages/Pets1.razor:

@page "/pets1"

<h1>Pets</h1>

<TableTemplate Items="pets" Context="pet">
    <TableHeader>
        <th>ID</th>
        <th>Name</th>
    </TableHeader>
    <RowTemplate>
        <td>@pet.PetId</td>
        <td>@pet.Name</td>
    </RowTemplate>
</TableTemplate>

@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; }
    }
}

Como alternativa, você pode alterar o nome do parâmetro usando o Context atributo no RenderFragment<TValue> elemento filho. No exemplo a seguir, o Context é definido em RowTemplate em vez de TableTemplate:

Pages/Pets2.razor:

@page "/pets2"

<h1>Pets</h1>

<TableTemplate Items="pets">
    <TableHeader>
        <th>ID</th>
        <th>Name</th>
    </TableHeader>
    <RowTemplate Context="pet">
        <td>@pet.PetId</td>
        <td>@pet.Name</td>
    </RowTemplate>
</TableTemplate>

@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; }
    }
}

Os argumentos de componente do tipo RenderFragment<TValue> têm um parâmetro implícito chamado 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 Pet propriedade:

Pages/Pets3.razor:

@page "/pets3"

<h1>Pets</h1>

<TableTemplate Items="pets">
    <TableHeader>
        <th>ID</th>
        <th>Name</th>
    </TableHeader>
    <RowTemplate>
        <td>@context.PetId</td>
        <td>@context.Name</td>
    </RowTemplate>
</TableTemplate>

@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; }
    }
}

Ao usar componentes de tipo genérico, o parâmetro de tipo é inferido, se possível. No entanto, você pode especificar explicitamente o tipo com um atributo que tem um nome que corresponda ao parâmetro de tipo, que está TItem no exemplo anterior:

Pages/Pets4.razor:

@page "/pets4"

<h1>Pets</h1>

<TableTemplate Items="pets" TItem="Pet">
    <TableHeader>
        <th>ID</th>
        <th>Name</th>
    </TableHeader>
    <RowTemplate>
        <td>@context.PetId</td>
        <td>@context.Name</td>
    </RowTemplate>
</TableTemplate>

@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; }
    }
}

Recursos adicionais

Componentes modelo são componentes que aceitam 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. Os componentes modelo permitem criar componentes de nível superior que são mais reutilizáveis do que os componentes regulares. Alguns exemplos incluem:

  • Um componente de tabela que permite que um usuário especifique modelos para o cabeçalho, linhas e rodapé da tabela.
  • Um componente de lista que permite que um usuário especifique um modelo para renderizar itens em uma lista.

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, consulte ASP.NET Core Razor componentes.

Geralmente, os componentes modelo são tipado genericamente, como demonstra o componente a seguir TableTemplate . O tipo <T> genérico neste exemplo é usado para renderizar IReadOnlyList<T> valores, que nesse caso é uma série de linhas de animais de estimação em um componente que exibe uma tabela de animais de estimação.

Shared/TableTemplate.razor:

@typeparam TItem

<table class="table">
    <thead>
        <tr>@TableHeader</tr>
    </thead>
    <tbody>
        @foreach (var item in Items)
        {
            <tr>@RowTemplate(item)</tr>
        }
    </tbody>
</table>

@code {
    [Parameter]
    public RenderFragment TableHeader { get; set; }

    [Parameter]
    public RenderFragment<TItem> RowTemplate { get; set; }

    [Parameter]
    public IReadOnlyList<TItem> Items { get; set; }
}

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, <TableHeader>...</TableHeader> e <RowTemplate>...<RowTemplate> forneça RenderFragment<TValue> modelos para TableHeader e RowTemplate do TableTemplate componente.

Especifique o Context atributo 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 Context atributo aparece no TableTemplate elemento e se aplica a todos os RenderFragment<TValue> parâmetros de modelo.

Pages/Pets1.razor:

@page "/pets1"

<h1>Pets</h1>

<TableTemplate Items="pets" Context="pet">
    <TableHeader>
        <th>ID</th>
        <th>Name</th>
    </TableHeader>
    <RowTemplate>
        <td>@pet.PetId</td>
        <td>@pet.Name</td>
    </RowTemplate>
</TableTemplate>

@code {
    private List<Pet> pets = new List<Pet>
    {
        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; }
    }
}

Como alternativa, você pode alterar o nome do parâmetro usando o Context atributo no RenderFragment<TValue> elemento filho. No exemplo a seguir, o Context é definido em RowTemplate em vez de TableTemplate:

Pages/Pets2.razor:

@page "/pets2"

<h1>Pets</h1>

<TableTemplate Items="pets">
    <TableHeader>
        <th>ID</th>
        <th>Name</th>
    </TableHeader>
    <RowTemplate Context="pet">
        <td>@pet.PetId</td>
        <td>@pet.Name</td>
    </RowTemplate>
</TableTemplate>

@code {
    private List<Pet> pets = new List<Pet>
    {
        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; }
    }
}

Os argumentos de componente do tipo RenderFragment<TValue> têm um parâmetro implícito chamado 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 Pet propriedade:

Pages/Pets3.razor:

@page "/pets3"

<h1>Pets</h1>

<TableTemplate Items="pets">
    <TableHeader>
        <th>ID</th>
        <th>Name</th>
    </TableHeader>
    <RowTemplate>
        <td>@context.PetId</td>
        <td>@context.Name</td>
    </RowTemplate>
</TableTemplate>

@code {
    private List<Pet> pets = new List<Pet>
    {
        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; }
    }
}

Ao usar componentes de tipo genérico, o parâmetro de tipo é inferido, se possível. No entanto, você pode especificar explicitamente o tipo com um atributo que tem um nome que corresponda ao parâmetro de tipo, que está TItem no exemplo anterior:

Pages/Pets4.razor:

@page "/pets4"

<h1>Pets</h1>

<TableTemplate Items="pets" TItem="Pet">
    <TableHeader>
        <th>ID</th>
        <th>Name</th>
    </TableHeader>
    <RowTemplate>
        <td>@context.PetId</td>
        <td>@context.Name</td>
    </RowTemplate>
</TableTemplate>

@code {
    private List<Pet> pets = new List<Pet>
    {
        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; }
    }
}

Recursos adicionais