Creemos un componente
angular para crear un conjunto de casillas de verificación de un grupo lógico específico. El componente se escribirá con ideas de reutilización. ¿Qué significa esto? Aquí hay un ejemplo a continuación:
Imagine que tiene la tarea de editar usuarios. Al editar, generalmente se abre un formulario con todos los campos. Un usuario puede tener uno o varios roles de la lista de
"Adimin", "Director", "Profesor", "Estudiante".Para implementar la elección múltiple de roles, se decidió dibujar en el formulario una casilla de verificación para cada rol. Al marcar o desmarcar, los roles de los usuarios cambiarán.
Primero, creemos un componente principal (es decir, una página para el formulario) que ya contendrá nuestro componente
grupo de casillas de verificación .
export class AppComponent implements OnInit , , , ]; public userModel = ; constructor() ngOnInit(): void }
Como puede ver aquí, hice un código duro de todos los roles posibles, pero en una aplicación real, los roles probablemente se solicitarán de la base de datos. Para simular nuestro HTTP al servidor, asigné los mismos valores a otra variable con un ligero retraso.
//app.component.ts userRolesOptions = new Array<any>(); ngOnInit(): void { setTimeout(() => { this.userRolesOptions = this.userRoles; }, 1000); // 1 }
Ahora comencemos a crear un componente de grupo de casilla de verificación generalizado, que se puede
reutilizar sin ningún problema en todos los casos cuando se necesita un grupo de casilla de verificación.
Primero necesitamos tal clase CheckboxItem.ts
export class CheckboxItem { value: string; label: string; checked: boolean; constructor(value: any, label: any, checked?: boolean) { this.value = value; this.label = label; this.checked = checked ? checked : false; } }
CheckboxComponent lo utilizará para representar todas las opciones posibles (en nuestro caso, estos son roles) y guardar desde el estado (la opción está seleccionada o no). Tenga en cuenta que la propiedad "marcada" es un parámetro opcional en el constructor y su valor predeterminado será falso, es decir, todos los valores no se seleccionarán primero. Esto es adecuado cuando creamos un nuevo usuario sin un solo rol.
A continuación, modificaremos ligeramente nuestra función que simula la solicitud del servidor, de modo que podamos asignar entre la respuesta JSON y la matriz
userRolesOptions = new Array<CheckboxItem>(); ngOnInit(): void { setTimeout(() => { this.userRolesOptions = this.userRoles.map(x => new CheckboxItem(x.id, x.name)); }, 1000); }
No importa qué estructura JSON nos devuelva el servidor. Cada casilla de verificación HTML siempre tiene un valor y una descripción. En nuestro caso, hacemos mapeo "id" con "valor" y "nombre" con "etiqueta".
El valor se utilizará como clave o id para la opción, y la
etiqueta es solo una cadena de descripción que el usuario lee.
El siguiente paso es crear un CheckboxGroupComponent. Se ve así:
@Component({ selector: 'checkbox-group', templateUrl: './checkbox-group.component.html', styleUrls: ['./checkbox-group.component.css'] }) export class CheckboxGroupComponent implements OnInit { @Input() options = Array<CheckboxItem>(); constructor() { } ngOnInit() {} }
Este no es un tutorial angular, por lo que no explicaré los detalles del marco. Quién necesita leer en la documentación oficial.
La propiedad
@Input llamada
opciones contendrá una lista de todos los valores posibles que no están seleccionados de forma predeterminada. Nuestra plantilla de componentes HTML representará tantas casillas de verificación como contenga esta lista.
Este es el html para CheckboxGroupComponent:
<div *ngFor=”let item of options”> <input type=”checkbox” [(ngModel)]=”item.checked”>{{item.label}} </div>
Tenga en cuenta que usé ngModel para vincular cada propiedad de
elemento "marcado" de la lista de
opciones .
El paso final es agregar nuestro componente recién creado a la plantilla principal de AppComponent.
// somewhere in AppComponent html template <checkbox-group [options]=”userRolesOptions”></checkbox-group>
El resultado debería ser así:

Para obtener todas las opciones seleccionadas actualmente, crearemos un evento de salida que, con cualquier clic en una de las casillas de verificación, devolverá nuestra lista de las seleccionadas. Algo como esto: [1,2,4]
En la plantilla CheckboxGroupComponent, asociamos el
evento change con la nueva función.
<div *ngFor=”let item of options”> <input type=”checkbox” [(ngModel)]=”item.checked” (change)=”onToggle()”>{{item.label}} </div>
Es hora de implementar esta misma función:
export class CheckboxGroupComponent implements OnInit { @Input() options = Array<CheckboxItem>(); @Output() toggle = new EventEmitter<any[]>(); constructor() {} ngOnInit(){} onToggle() { const checkedOptions = this.options.filter(x => x.checked); this.selectedValues = checkedOptions.map(x => x.value); this.toggle.emit(checkedOptions.map(x => x.value)); } }
Suscríbase a este evento (propiedad de
salida con el nombre de
alternar ) en la plantilla AppComponent.
<checkbox-group [options]=”userRolesOptions” (toggle)=”onRolesChange($event)”></checkbox-group>
Y asigne el resultado de retorno (roles seleccionados) en userModel.
export class CheckboxGroupComponent implements OnInit { //.. onRolesChange(value) { this.userModel.roles = value; console.log('Model role:' , this.userModel.roles); } }
Ahora, cada vez que haga clic en la casilla de verificación, verá una lista de roles seleccionados en la consola. Más precisamente, su identificación. Por ejemplo, si elijo los roles de
Administrador y
Profesor , obtengo "Modelo de roles: (2) [1, 3]".
El componente está casi completo y listo para su reutilización. Lo último que queda es hacer que la casilla de verificación sea compatible con la inicialización de grupo Esto será necesario en el caso en que haremos la edición del usuario. Antes de eso, debemos hacer una solicitud al servidor para obtener la lista actual de roles de usuario e inicializar CheckboxGroupComponent.
Tenemos dos formas de hacer esto.
El primero es usar el constructor de la clase CheckboxItem y usar el parámetro opcional "verificado". En el lugar donde hicimos el mapeo.
//AppComponent.ts setTimeout(() => { this.userRolesOptions = this.userRoles.map(x => new CheckboxItem(x.id, x.name, true)); }, 1000); //
La segunda forma es agregar otra lista de
Valores seleccionados para inicializar nuestro componente.
<checkbox-group [options]=”userRolesOptions” [selectedValues]=”userModel.roles” (toggle)=”onRolesChange($event)”></checkbox-group>
Imaginemos que ya hemos realizado una solicitud para el usuario actual y que un modelo con tres roles proviene de la base de datos.
//AppComponent.ts public userModel = { id: 1, name: 'Vlad', roles: [1,2,3] }; constructor() { } //rest of the code
En CheckboxGroupComponent, inicializamos todas las propiedades "marcadas" de cada casilla de verificación como verdaderas si la identificación del rol está contenida en la lista de
Valores seleccionados .
//CheckboxGroupComponent.ts ngOnInit() { this.selectedValues.forEach(value => { const element = this.options.find(x => x.value === value); if (element) { element.checked = true; } }); }
Como resultado, debería obtener el siguiente resultado:
Aquí usé estilos de material angularAl inicio, habrá un retraso de un segundo antes de que Angular dibuje todas las casillas de verificación en la página. Esto simula el tiempo dedicado a cargar roles desde la base de datos.
Es importante tener en cuenta que puede obtener todos los roles seleccionados suscribiéndose a un evento (alternar) o simplemente usar la propiedad "marcada" en cada objeto de elemento de la lista
userRolesOptions ubicada en el componente
principal . Esto se debe a que el enlace a la lista se pasa a través de @Input (enlace) y todos los cambios dentro del objeto se sincronizarán.
const checkedOptions = this.userRolesOptions.filter(x => x.checked);
Dicho componente se puede diseñar a su gusto y usarse para cualquier tarea en la que se necesite selección múltiple.
¡Gracias por leer este artículo! Espero que hayas disfrutado creando el componente Angular con ideas de reutilización.
PD: Si el artículo será popular, publicaré la segunda parte pequeña, donde se escribe el mismo ejemplo usando Angular Reactive Forms.