3
respostas

[Dúvida] Duvida, porque não usar os @bind

Bom dia, Uma duvida me surgiu visto que os elementos mudBlezor possuem @bind-value, e o MudSelect tem o @bind-SelectedValues por que não utiliza-los?

meu mudSelect:

<MudSelect Class="mt-4" 
           Label="Gêneros"
           Variant="Variant.Filled"
           AnchorOrigin="Origin.BottomCenter"
           T="GeneroResponse" 
           ToStringFunc="converterGenero"
           MultiSelection="true"
           @bind-SelectedValues = "generosSelect">

    @if (generos is not null)
    {
        foreach (var _genero in generos)
        {
            <MudSelectItem Value="_genero" />
        }
    }
</MudSelect>
...

@code {
...
private IEnumerable<GeneroResponse> generosSelect = new List<GeneroResponse>();
...
}
3 respostas

meu page completo:

@inject ArtistasAPI artistaAPI
@inject GeneroAPI generoAPI
@inject MusicasApi musicaAPI
@inject NavigationManager navigationManager

@page "/CadastrarMusica"

<MudPaper Class="px-8 pt-2 pb-4 mx-12 my-8" Justify="Justify.Center">

    <MudText Class="mt-8" Typo="Typo.h4">Cadastro de Música</MudText>

    <MudForm>
        @* Nome Musica *@
        <MudTextField Class="mt-4" T="string" Placeholder="Nome da música/canção"
                      @bind-Value="nome"
                      Variant="Variant.Outlined"
                      Required="true"
                      RequiredError="Nome é obrigatório." />

        @* Select Artista *@
        <MudSelect Class="mt-4" T="ArtistaResponse" Label="Artistas"
                   Variant="Variant.Filled"
                   AnchorOrigin="Origin.BottomCenter"
                   ToStringFunc="converterArtista"
                   @bind-Value="artista">
            @if (artistas is not null)
            {
                foreach (var _artista in artistas)
                {
                    <MudSelectItem Value="_artista" />
                }
            }
        </MudSelect>

        @* ano lancamento *@
        <MudNumericField Class="mt-4"
                         Step="1"
                         Min="1900"
                         Max="GetAnoLancamentoMax()"
                         Placeholder="Ano de lançamento"
                         @bind-Value="anoLancamento"
                         Variant="Variant.Outlined"
                         Required="true"
                         RequiredError="Ano é obrigatório." />

        @* multi select generos *@
        <MudSelect Class="mt-4"
                   Label="Gêneros"
                   Variant="Variant.Filled"
                   AnchorOrigin="Origin.BottomCenter"
                   T="GeneroResponse"
                   ToStringFunc="converterGenero"
                   MultiSelection="true"
                   @bind-SelectedValues="generosSelect">

            @if (generos is not null)
            {
                foreach (var _genero in generos)
                {
                    <MudSelectItem Value="_genero" />
                }
            }
        </MudSelect>

        @* Botoes Cadastrar/Voltar*@
        <MudStack Justify="Justify.FlexEnd" Row="true" Class="mt-5">
            <MudButton Variant="Variant.Filled"
                       Color="Color.Info"
                       Class="ml-auto"
                       OnClick="Voltar">
                Voltar
            </MudButton>
            <MudButton Variant="Variant.Filled"
                       Color="Color.Primary"
                       Class="ml-1"
                       OnClick="Cadastrar">
                Cadastrar
            </MudButton>
        </MudStack>

        @* Alerta de seleção *@
        @if (generosSelect is not null)
        {
            foreach (var genero in generosSelect)
            {
                <MudAlert Severity="Severity.Info">@(genero.Nome) adicionado como gênero da música.</MudAlert>
            }
        }
    </MudForm>
</MudPaper>

@code {
    private int? anoLancamento;
    private string? nome;
    private ArtistaResponse? artista;
    // private GeneroResponse? genero;

    private ICollection<ArtistaResponse>? artistas;
    private ICollection<GeneroResponse>? generos;
    private IEnumerable<GeneroResponse> generosSelect = new List<GeneroResponse>();

    private int GetAnoLancamentoMax()
    {
        return DateTime.Now.AddYears(1).Year;
    }

    protected override async void OnInitialized()
    {
        artistas = await artistaAPI.GetArtistasAsync();
        generos = await generoAPI.GetGenerosAsync();
    }

    private async Task Cadastrar()
    {
        ICollection<GeneroRequest>? generosRequest = new List<GeneroRequest>();

        if (generosSelect is not null)
        {
            foreach (var genero in generosSelect)
            {
                generosRequest!.Add(new GeneroRequest(genero.Nome, genero.Descricao));
            }
        }

        var request = new MusicaRequest(nome!, artista!.Id, (int)anoLancamento!, generosRequest);
        await musicaAPI.AddMusicaAsync(request);
        navigationManager.NavigateTo("/Artistas");
    }

    private async Task Voltar()
    {
        navigationManager.NavigateTo("/Artistas");
    }

    Func<ArtistaResponse, string> converterArtista = p => p?.Nome;
    Func<GeneroResponse, string> converterGenero = p => p?.Nome;
}

Obs tive que mudar a assinatura GeneroRequest, pois a descrição nula estava causando erro...

namespace ScreenSound.Web.Requests
{
    public record GeneroRequest(string Nome, string? Descricao)
    {
    }
}

Olá, Marcelo! Tudo joia?

O @bind é uma funcionalidade poderosa do Blazor que simplifica a ligação de dados entre componentes de UI e propriedades do seu código. No caso do MudSelect, o @bind-SelectedValues é extremamente útil para manter a lista de itens selecionados sincronizada com a propriedade generosSelect no seu código.

O uso do @bind elimina a necessidade de escrever métodos adicionais para tratar mudanças de valor, pois ele atualiza automaticamente a propriedade associada sempre que o valor do componente muda. Isso reduz a quantidade de código e torna a aplicação mais limpa e fácil de manter.

Por exemplo, no seu código, ao usar @bind-SelectedValues="generosSelect", você está dizendo ao Blazor para atualizar generosSelect sempre que o usuário selecionar ou desmarcar um item no MudSelect. Isso é feito automaticamente, sem a necessidade de um método ValueChanged.

Aqui está um exemplo prático:

<MudSelect Class="mt-4" 
           Label="Gêneros"
           Variant="Variant.Filled"
           AnchorOrigin="Origin.BottomCenter"
           T="GeneroResponse" 
           ToStringFunc="converterGenero"
           MultiSelection="true"
           @bind-SelectedValues="generosSelect">

    @if (generos is not null)
    {
        foreach (var _genero in generos)
        {
            <MudSelectItem Value="_genero" />
        }
    }
</MudSelect>

@code {
    private IEnumerable<GeneroResponse> generosSelect = new List<GeneroResponse>();
}

Com o @bind, você não precisa de um método GeneroSelecionado para atualizar generosSelect. O Blazor faz isso automaticamente para você.

Por outro lado, se você precisar de lógica adicional quando o valor mudar (por exemplo, atualizar outra parte do estado da aplicação ou fazer uma chamada de API), você pode usar o evento ValueChanged em vez do @bind. Isso dá mais controle sobre o que acontece quando o valor é alterado.

Espero ter ajudado e bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓.