Dada una lista de casillas de verificación vinculadas a lo mismo formControlName
, ¿cómo puedo producir una matriz de valores de casilla de verificación vinculados al formControl
, en lugar de simplementetrue
/ false
?
Ejemplo:
<form [formGroup]="checkboxGroup">
<input type="checkbox" id="checkbox-1" value="value-1" formControlName="myValues" />
<input type="checkbox" id="checkbox-2" value="value-2" formControlName="myValues" />
<input type="checkbox" id="checkbox-3" value="value-2" formControlName="myValues" />
</form>
checkboxGroup.controls['myValues'].value
actualmente produce:
true or false
Lo que quiero que produzca:
['value-1', 'value-2', ...]
javascript
angular
checkbox
angular2-forms
Reaccionando a AngularVues
fuente
fuente
Respuestas:
Con la ayuda de silenntsod answer, escribí una solución para obtener valores en lugar de estados en mi formBuilder.
Utilizo un método para agregar o eliminar valores en formArray. Puede que sea un mal enfoque, ¡pero funciona!
componente.html
componente.ts
Cuando envío mi formulario, por ejemplo, mi modelo se ve así:
Solo falta una cosa, una función para completar el formArray si su modelo ya tiene valores comprobados.
fuente
myChoices: new FormArray([], Validators.required)
Este es un buen lugar para usar
FormArray
https://angular.io/docs/ts/latest/api/forms/index/FormArray-class.htmlPara empezar,
FormBuilder
crearemos nuestro conjunto de controles con un o con un nuevoFormArray
FormBuilder
nuevo FormArray
Es bastante fácil de hacer, pero luego cambiaremos nuestra plantilla y dejaremos que el motor de plantillas maneje cómo nos vinculamos a nuestros controles:
template.html
Aquí estamos iterando sobre nuestro conjunto de
FormControls
en nuestromyValues
FormArray
y para cada control estamos vinculando[formControl]
a ese control en lugar de alFormArray
control y<div>{{checkboxGroup.controls['myValues'].value}}</div>
producetrue,false,true
al mismo tiempo que hacemos que la sintaxis de la plantilla sea un poco menos manual.Puede usar este ejemplo: http://plnkr.co/edit/a9OdMAq2YIwQFo7gixbj?p=preview para hurgar
fuente
*ngFor="let control of checkboxGroup.controls['myValues'].controls ; let i=index""
Es significativamente más fácil hacer esto en Angular 6 que en versiones anteriores, incluso cuando la información de la casilla de verificación se completa de forma asincrónica desde una API.
Lo primero que debemos darnos cuenta es que, gracias a la
keyvalue
tubería de Angular 6, ya no necesitamos usarFormArray
más, y en su lugar podemos anidar unFormGroup
.Primero, pase FormBuilder al constructor
Luego inicialice nuestro formulario.
Cuando nuestros datos de opciones de casilla de verificación están disponibles, iterarlos y podemos enviarlos directamente al anidado
FormGroup
como un nombreFormControl
, sin tener que depender de matrices de búsqueda indexadas por número.Finalmente, en la plantilla solo necesitamos iterar la
keyvalue
de las casillas de verificación: no adicionallet index = i
, y las casillas de verificación estarán automáticamente en orden alfabético: mucho más limpio.fuente
const checkboxes = ..
fuera del foreach;)Si está buscando valores de casilla de verificación en formato JSON
Ejemplo completo aquí .
Pido disculpas por usar nombres de países como valores de casilla de verificación en lugar de los de la pregunta. Explicación adicional -
Crea un FormGroup para el formulario
Deje que cada casilla de verificación sea un FormGroup construido a partir de un objeto cuya única propiedad es el valor de la casilla de verificación.
La matriz de FormGroups para las casillas de verificación se utiliza para establecer el control de los 'países' en el formulario principal.
En la plantilla, use una tubería para obtener el nombre del control de casilla de verificación
fuente
TL; DR
Esto también me sorprendió a veces, así que probé los enfoques FormArray y FormGroup.
La mayoría de las veces, la lista de casillas de verificación se completó en el servidor y la recibí a través de API. Pero a veces tendrá un conjunto estático de casillas de verificación con su valor predefinido. Con cada caso de uso, se utilizará el FormArray o FormGroup correspondiente.
En aras de la simplicidad, imagine que tiene un formulario de creación de producto simple con
Primero, configuré un formulario con solo el nombre del producto formControl. Es un campo obligatorio.
Dado que la categoría se está procesando dinámicamente, tendré que agregar estos datos al formulario más tarde, una vez que los datos estén listos.
Hay dos enfoques para crear la lista de categorías.
1. Matriz de formas
Esto
buildCategoryFormGroup
me devolverá un FormArray. También toma una lista de valores seleccionados como argumento, por lo que si desea reutilizar el formulario para editar datos, podría ser útil. Para el propósito de crear un nuevo formulario de producto, aún no es aplicable.Observó que cuando intenta acceder a los valores de formArray. Se verá así
[false, true, true]
. Para obtener una lista de ID seleccionados, se requirió un poco más de trabajo para verificar de la lista, pero según el índice de la matriz. No me suena bien, pero funciona.Por eso se me ocurrió usar
FormGroup
para el caso2. Formar grupo
La diferencia de formGroup es que almacenará los datos del formulario como el objeto, que requiere una clave y un control de formulario. Por lo tanto, es una buena idea establecer la clave como categoryId y luego podemos recuperarla más tarde.
El valor del grupo de formularios se verá así:
Pero la mayoría de las veces queremos obtener solo la lista de categoryIds como
["category2", "category3"]
. También tengo que escribir un get para tomar estos datos. Me gusta más este enfoque en comparación con formArray, porque en realidad podría tomar el valor del formulario en sí.3. Se seleccionó un validador personalizado para marcar al menos una casilla de verificación
Hice que el validador marcara al menos X la casilla de verificación seleccionada, de forma predeterminada, solo se verificará con una casilla de verificación.
fuente
No veo una solución aquí que responda completamente a la pregunta utilizando formas reactivas en su máxima extensión, así que aquí está mi solución para lo mismo.
Resumen
Aquí está la esencia de la explicación detallada junto con un ejemplo de StackBlitz.
FormArray
para las casillas de verificación e inicialice el formulario.valueChanges
observable es perfecto para cuando desea que el formulario muestre algo pero almacene algo más en el componente. Mapear eltrue
/false
valores a los valores deseados aquí.false
valores en el momento del envío.valueChanges
observable.Ejemplo de StackBlitz
Explicación detallada
Utilice FormArray para definir el formulario
Como ya se mencionó en la respuesta marcada como correcta.
FormArray
es el camino a seguir en los casos en los que preferiría obtener los datos en una matriz. Entonces, lo primero que debe hacer es crear el formulario.Esto solo establecerá el valor inicial de todas las casillas de verificación en
false
.A continuación, necesitamos registrar estas variables de formulario en la plantilla e iterar sobre la
checkboxes
matriz (NO losFormArray
datos de la casilla de verificación) para mostrarlos en la plantilla.Hacer uso de los cambios de valor observables
Aquí está la parte que no veo mencionada en ninguna respuesta dada aquí. En situaciones como esta, donde nos gustaría mostrar dichos datos pero almacenarlos como otra cosa, el
valueChanges
observable es muy útil. UtilizandovalueChanges
, podemos observar los cambios encheckboxes
y luegomap
los valorestrue
/false
recibidos de losFormArray
datos deseados. Tenga en cuenta que esto no cambiará la selección de las casillas de verificación, ya que cualquier valor verdadero que se pase a la casilla de verificación lo marcará como marcado y viceversa.Esto básicamente asigna los
FormArray
valores a lacheckboxes
matriz original y devuelve elvalue
en caso de que la casilla de verificación esté marcada comotrue
, de lo contrario, regresafalse
. ElemitEvent: false
es importante aquí, ya establecer elFormArray
valor sin que hará quevalueChanges
para emitir un evento creando un bucle sin fin. Al estableceremitEvent
enfalse
, nos aseguramos de que elvalueChanges
observable no se emita cuando establecemos el valor aquí.Filtra los valores falsos
No podemos filtrar directamente los
false
valores en elFormArray
porque hacerlo estropearía la plantilla, ya que están vinculados a las casillas de verificación. Entonces, la mejor solución posible es filtrar losfalse
valores durante el envío. Utilice el operador de propagación para hacer esto.Esto básicamente filtra los valores falsos de
checkboxes
.Darse de baja de valueChanges
Por último, no olvide darse de baja de
valueChanges
Nota: Hay un caso especial en el que un valor no se puede ajustar a la
FormArray
devalueChanges
, por ejemplo, si el valor de la casilla de verificación se establece en el número0
. Esto hará que parezca que la casilla de verificación no se puede seleccionar, ya que al seleccionar la casilla de verificación se estableceráFormControl
el número0
(un valor falso) y, por lo tanto, se mantendrá sin marcar. Sería preferible no usar el número0
como un valor, pero si es necesario, debe establecer condicionalmente0
un valor verdadero, digamos cadena'0'
o simplemente simpletrue
y luego, al enviarlo, convertirlo de nuevo al número0
.Ejemplo de StackBlitz
StackBlitz también tiene código para cuando desea pasar valores predeterminados a las casillas de verificación para que se marquen como marcadas en la interfaz de usuario.
fuente
Haga un evento cuando se haga clic y luego cambie manualmente el valor de verdadero por el nombre de lo que representa la casilla de verificación, luego el nombre o verdadero evaluará lo mismo y podrá obtener todos los valores en lugar de una lista de verdadero / falso. Ex:
componente.html
componente.ts
Esto detecta el evento después de que Angular Forms ya lo cambió a verdadero o falso, si es cierto, cambio el nombre al nombre de lo que representa la casilla de verificación, que si es necesario, también se evaluará como verdadero si se verifica verdadero / falso como bien.
fuente
Si desea utilizar una forma reactiva angular ( https://angular.io/guide/reactive-forms ).
Puede usar un control de formulario para administrar el valor de salida del grupo de casillas de verificación.
componente
html
checklistState
Gestiona el modelo / estado de las entradas de la lista de verificación. Este modelo le permite asignar el estado actual a cualquier formato de valor que necesite.
Modelo:
checklist
Control de formularioEste control almacena el valor que le gustaría guardar como, por ejemplo,
salida de valor:
"value_1,value_2"
Vea la demostración en https://stackblitz.com/edit/angular-multi-checklist
fuente
Mi solución: lo resolví para Angular 5 con Vista de material
La conexión es a través de
De esta manera, puede funcionar para múltiples matrices de casillas de verificación en una forma. Simplemente configure el nombre de la matriz de controles para conectarse cada vez.
Al final, podrá guardar el formulario con una matriz de ID de registros originales para guardar / actualizar.
fuente
PARTE DE LA PLANTILLA: -
PARTE DEL CONTROLADOR: -
fuente
Agregue mis 5 centavos) Mi modelo de pregunta
template.html
componente.ts
fuente
Respuesta relacionada a @ nash11, así es como produciría una matriz de valores de casilla de verificación
Y
tener una casilla de verificación que también seleccione Todas las casillas de verificación:
https://stackblitz.com/edit/angular-checkbox-custom-value-with-selectall
fuente