martes, 6 de octubre de 2020
Los parámetros son el mecanismo básico de comunicación entre componentes, pues permiten que un componente padre o contenedor puede especificar, utilizando atributos, los valores que desea enviar de forma individualizada a los componentes utilizados en su interior. Un ejemplo lo vemos en el siguiente bloque de código, donde indicamos a un componente el número de veces que debe mostrar un contenido:
¡Bienvenidos a los cascading values and parameters, o valores y parámetros en cascada!
Los valores de los parámetros decorados con el atributo
Obviamente esto supondría una limitación en caso de existir más de un valor del mismo tipo, como en el siguiente ejemplo, donde queremos propagar valores para el color de texto y de fondo a los componentes descendientes:
En estos casos debemos establecer un nombre para los valores en cascada, de forma que luego podamos referirnos a ellos de forma inequívoca:
Publicado en Variable not found.
<NumberList Count="10" />
Desde el punto de vista del componente <NumberList>
, la recepción de este parámetro es trivial, simplemente indicando el atributo [Parameter]
en su propiedad pública Count
:<ul>
@for (int i = 0; i < Count; i++)
{
<li>@i</li>
}
</ul>
@code {
[Parameter]
public int Count { get; set; }
}
Este mecanismo va bien si queremos pasar el parámetro a un componente específico mediante atributos, pero puede haber ocasiones en las que nos interesa pasar parámetros a todos los componentes que se encuentren por debajo en la estructura jerárquica sin tener que ir pasándolos de uno en uno. Esto puede ser especialmente útil si, como en el diagrama, existen varios niveles de componentes en los que deseamos tener acceso a la misma información.¡Bienvenidos a los cascading values and parameters, o valores y parámetros en cascada!
Pasar valores a todos los componentes descendientes
Cuando un componente necesita pasar valores a todos los componentes que se encuentren por debajo de él en el árbol, debe utilizar la etiqueta<CascadingValue>
como se muestra a continuación:<CascadingValue Value="UserInfo">
<UserHeader>...</UserHeader>
<UserDetails>...</UserDetails>
</CascadingValue>
@code {
// UserInfo podríamos obtenerlo de algún sitio
private UserInformation UserInfo = new UserInformation() { Name="José M. Aguilar" }
}
Fijaos que enLo que conseguimos conValue
podemos introducir cualquier tipo de objeto .NET, incluso expresiones o referencias al componente actual comoValue="this"
.
<CascadingValue>
es añadir a la cascada un valor de tipo UserInformation
que los descendientes podrán obtener directamente declarando un parámetro en cascada, como se puede ver a continuación:@* File: UserDetails.razor *@
<h2>User details</h2>
@UserInfo.Name
@code {
[CascadingParameter]
public UserInformation UserInfo { get; set; }
}
El funcionamiento es idéntico a los parámetros tradicionales expresados como atributos al instanciar el componente, exceptuando que aquí usamos [CascadingParameter]
para indicar que el parámetro debe ser poblado desde los valores introducidos en la cascada en niveles superiores de la jerarquía de componentes.Los valores de los parámetros decorados con el atributo
[CascadingParameter]
se enlazarán durante la inicialización del componente a los valores en cascada del mismo tipo definidos en cualquier nivel anterior de la jerarquía de componentes. Así, en el ejemplo anterior, el parámetro UserInfo
es enlazado correctamente porque existe un valor en la cascada de tipo UserInformation
.Obviamente esto supondría una limitación en caso de existir más de un valor del mismo tipo, como en el siguiente ejemplo, donde queremos propagar valores para el color de texto y de fondo a los componentes descendientes:
<CascadingValue Value="_backgroundColor">
<CascadingValue Value="_textColor">
<Title Text="This is the title"></Title>
...
</CascadingValue>
</CascadingValue>
@code {
string _backgroundColor = "blue";
string _textColor = "white";
}
En el bloque de código anterior, fijaos que estamos estableciendo dos valores en cascada de tipo string
, pero los componentes descendientes que quieran utilizarlos no tendrán forma de distinguirlos al ser ambos del mismo tipo. La aplicación no fallará, pero los parámetros en cascada no serán poblados.En estos casos debemos establecer un nombre para los valores en cascada, de forma que luego podamos referirnos a ellos de forma inequívoca:
<h1>Demo page</h1>
<CascadingValue Value="_backgroundColor" Name="BackgroundColor">
<CascadingValue Value="_textColor" Name="TextColor">
<Title Text="This is the title"></Title>
</CascadingValue>
</CascadingValue>
@code {
string _backgroundColor = "blue";
string _textColor = "white";
}
Y así, ya desde los componentes que los consumen podremos indicar a qué valores nos referimos en cada caso:@* File: Title.razor *@
<h2 style="background-color: @BackgroundColor; color: @TextColor">@Text</h2>
@code {
[Parameter]
public string Text { get; set; }
[CascadingParameter(Name = "TextColor")]
public string TextColor { get; set; }
[CascadingParameter(Name = "BackgroundColor")]
public string BackgroundColor { get; set; }
}
Por último, vale la pena comentar que el uso de cascading parameters puede tener algo de repercusión en el rendimiento, sobre todo en estructuras muy complejas, pues cada cambio del valor introducido en la cascada obligará a recorrer el árbol de componentes para actualizar los valores. Por esta razón, establecer a cierto la propiedad IsFixed
de <CascadingValue> es muy recomendable cuando estemos seguros de que el valor no cambiará, porque así informaremos al framework de que no es necesario que realice su seguimiento:<CascadingValue Value="LoggedUser" IsFixed="true">
...
Espero que os resulte útil :)
Publicado en Variable not found.
Aún no hay comentarios, ¡sé el primero!
Enviar un nuevo comentario