Comunicación entre componentes blazor

En este post vamos a ver como enviar o compartir información entre distintos componentes en blazor, para ello veremos las 3 formas de las que disponemos.

 

1 - Valores en cascada en blazor

Como vimos en el post de la creación de componentes, podemos enviar valores de un componente padre a uno hijo, para ello disponemos de dos opciones, utilizar la etiqueta <cascadingValue> o enviarlo como parámetro.

<!-- Elemento padre -->
<div class="main">
    <div class="content px-4">
        <CascadingValue Value="Bordercolor">
            @Body
        </CascadingValue>
    </div>
</div>
@code{
    private readonly string Bordercolor="red";
}

En el ejemplo anterior estamos enviando desde el elemento padre el parámetro BorderColor, el cual lo recibimos en el elemento hijo y lo aplicamos a la regla css.

<!-- Elemento hijo -->
<div class="row">
...
    <div class="col-sm-3" style="border: 1px solid @BorderColor">
        <b>Email:</b> @PersonalProfile.Email
    </div>
   ...
</div>

@code {
    [Parameter]
    public PersonalProfileDto PersonalProfile { get; set; }

    [CascadingParameter]
    public string BorderColor { get; set; }
}
  • Para ver más en detalle el funcionamiento, por favor revisa este post.

 

 

2 - EventCallbacks en blazor

Antes de continuar, decir que tanto EventCallback como EventCallback<T> fueron funcionalidades añadidas en blazor a partir de la versión de net core 3 preview 3.

 

Anteriormente para hacer una callback utilizabamos un delegado Action o Func, y la teoría sigue siendo la misma, la única diferencia es que anteriormente debíamos llamar al método StateHasChanged para indicarle al componente que hiciera el renderizado otra vez.

Lo que ha cambiado con la llegada de EventCallback es que hace esa llamada a StateHashChanged de forma automática.

 

Este tipo de eventos son muy útiles principalmente cuando un componente hijo debe generar un cambio en el componente padre.

Como podemos observar, en el elemento padre, mandamos al hijo un método como parámetro:

<!-- Parent Component -->
<div>@Mensaje</div>

<PerfilPersonal Profile="@Name"  OnClick="ClickCallback"></PerfilPersonal>

<Contacto />
@code{
    public string Mensaje = "Este es el mensaje en el elemento padre";

    void ClickCallback(string mensajeNuevo)
    {
        Mensaje = mensajeNuevo;
    }
}

El cual recibimos en el hijo como parámetro, indicando el tipo EventCallback<string> utilizamos string porque es el tipo de parámetro que recibe nuestro método.

[Parameter] 
public EventCallback<string> OnClick { get; set; }

Y para ejecutarlo, en el componente hijo debemos incluirlo como evento en alguno de nuestros items, en mi caso como onclick de un botón.

<button @onclick="@(() => OnClick.InvokeAsync($"Perfil del usuario {PersonalProfile.FirstName} {PersonalProfile.LastName} (enviado desde el hijo)."))">Lanzar evento padre</button>

Resultado:

event callback blazor

 

 

3 - State container en blazor

Finalmente vamos a ver el state container, el cual nos permite administrar múltiples componentes de nuestra aplicación simultáneamente, sin que estos estén relacionados entre sí directamente. 

 

Para ello debemos hacer una clase e inyectarla en los componentes donde queramos trabajar con ella. Cuando la definimos en nuestro contenedor de dependencias, debemos definirla como singleton si la aplicación es web assembly, o scoped si la aplicación es server side.

Para este ejemplo crearemos la lógica de cambiar el color de los títulos en nuestra aplicación,  pero una versión profesional podría ser el modo nocturno, la lógica es la misma, extendido a la aplicación completa. 

public class StateContainer
{
    public string SelectedCssClass { get; private set; }

    public event Action CambiarColor;

    public void AsignarColorCss(string newCssClass)
    {
        SelectedCssClass = newCssClass;
        ExecuteAction();
    }

    private void ExecuteAction() => CambiarColor?.Invoke();
}

Como podemos observar, nuestra clase StateContainer es una clase normal. Tiene una propiedad que almacena el valor de la clase css, un método público donde podemos cambiar ese valor y finalmente un evento CambiarColor que nos permite subscribirnos desde otros componentes.

 

En cada componente donde queremos tener acceso al valor que va a cambiar debemos suscribirnos al evento CambiarColor que exponse nuestra clase StateContainer.

@page "/perfil/{Name}"
@using WebPersonal.FrontEnd.WebApp.Componentes
@inject StateContainer stateContainer
@implements IDisposable

<div class="@stateContainer.SelectedCssClass">@Mensaje</div>

@code{
    protected override void OnInitialized()
    {
        stateContainer.CambiarColor += StateHasChanged;
    }

    public void Dispose()
    {
        stateContainer.CambiarColor -= StateHasChanged;
    }
}

Haciendo esto, nos aseguramos que cuando la clase cambie, el método StateHasChanged será invocado y así volverá a renderizar el componente con la nueva clase aplicada. 

No olvides implementar IDisposable, para que cuando no estés utilizando el componente este se desuscriba del evento CambiarColor. De lo contrario podría causar un memory leak

 

Finalmente solo nos queda crear los dos botones para cambiar del modo nocturno al normal.

 

Para ello lo único que debemos hacer es llamar con el evento onclick al método AsignarColorCss pasando como parámetro el valor deseado.

<!-- Boton modo "normal" -->
@inject StateContainer stateContainer

<button @onclick="SetCssNormal">Normal</button>

@code {

    void SetCssNormal()
    {
        stateContainer.AsignarColorCss("negro");
    }
}

<!-- Boton modo "nocturno" (rojo) -->
@inject StateContainer stateContainer

<button @onclick="SetCssNormal">Rojo</button>

@code {

    void SetCssNormal()
    {
        stateContainer.AsignarColorCss("rojo");
    }
}

Y este es el resultado, cuando pulsamos en el enlace, podemos ver como cambia el color

state container blazor

 

Conclusión

  • Hoy hemos visto tres formas diferentes de mantener comunicación entre diferentes componentes en blazor.
  • Hemos visto enviando información desde padres a hijos, utilizando los valores en cascada.
  • Hemos visto enviar información desde un hijo a un padre utilizando EventCallback.
  • Finalmente, hemos visto cómo compartir información entre cualquier número de componentes sin que estos estén directamente relacionados entre sí utilizando State Container.

 


Uso del bloqueador de anuncios adblock

Hola!

Primero de todo bienvenido a la web de NetMentor donde podrás aprender programación en C# y .NET desde un nivel de principiante hasta más avanzado.


Yo entiendo que utilices un bloqueador de anuncios como AdBlock, Ublock o el propio navegador Brave. Pero te tengo que pedir por favor que desactives el bloqueador para esta web.


Intento personalmente no poner mucha publicidad, la justa para pagar el servidor y por supuesto que no sea intrusiva; Si pese a ello piensas que es intrusiva siempre me puedes escribir por privado o por Twitter a @NetMentorTW.


Si ya lo has desactivado, por favor recarga la página.


Un saludo y muchas gracias por tu colaboración

© copyright 2024 NetMentor | Todos los derechos reservados | RSS Feed

Buy me a coffee Invitame a un café