J'essaie de définir par programme la valeur des cases à cocher Angular sur false
true
ou indeterminate
. Je comprends que je ne peux pas définir la case à cocher sur la valeur indeterminate
mais nous avons accès à [indeterminate]
sur l'entrée. Est-il possible de définir les trois états via ngModel
d'une manière ou d'une autre?
J'ai le code suivant qui fonctionne un peu, mais j'obtiens une erreur ExpressionChangedAfterItHasBeenCheckedError
.
HTML
checkedLabels(label): boolean { const index = this.selectedLabels.indexOf(label.objectId); this. indeterminateState = false; if (!this.selectedClients.length) { return false; } if (this.countInArray(this.selectedLabels, label.objectId) === this.selectedClients.length) { return true; } if (index >= 0) { this. indeterminateState = true; } } countInArray(array, value) { return array.reduce((n, x) => n + (x === value), 0); }
TS
<div *ngFor="let label of ClientLabels | async"> <label for="{{label.objectId}}">{{label.labelName}}</label> <input id="{{label.objectId}}" type="checkbox" name="group" [indeterminate]="checkedLabels()" [checked]="checkedLabels(label)" (change)="toggleSelectedLabels(label)" /> </div>
Ici, le cas d'utilisation est similaire à celui des étiquettes dans Gmail, sauf que les clients sont utilisés à la place d'un e-mail. Si tous les e-mails ont le même libellé, ils apparaissent comme cochés, mais si tous ne partagent pas le libellé, il affichera un indéterminé qui peut être parcouru à travers les trois états (vrai, faux, indéterminé).
Q1. Comment puis-je parcourir ces trois états de la même manière qu'avec gmail?
Q2. Pourquoi est-ce que j'obtiens le ExpressionChangedAfterItHasBeenCheckedError
avec la configuration actuelle?
Voici un Stackblitz de la progression actuelle https://stackblitz.com/edit/ angular-3bbutx
3 Réponses :
Pour rendre une case à cocher indéterminée, vous pouvez utiliser une directive
click(cliente: any) { let indeterminated=(!cliente.checked && !cliente.indeterminated) ? true : false; let checked=(!cliente.checked && cliente.indeterminated)?true:false cliente.indeterminated = indeterminated; cliente.checked=checked; }
Ensuite, votre case à cocher peut être comme
<input class="pull-left" type="checkbox" [indeterminate]="client.indeterminated" [checked]="client.checked" (click)="click(client)"/>
où
import { Directive, ElementRef,Input } from '@angular/core'; @Directive({ selector: '[indeterminate]' }) export class IndeterminateDirective { @Input() set indeterminate(value) { this.elem.nativeElement.indeterminate=value; } constructor(private elem: ElementRef) { } }
Voyant que vous avez deux variables "cochées" et "indéterminées", vous pouvez faire un cycle comme vous le souhaitez
Pouvons-nous ajouter facilement du faux? Donc, c'est cyclé entre les trois?
stackblitz.com/edit/… . Si vous cliquez sur rendre le cycle: indéterminé - coché - non coché. REMARQUE: lorsque indéterminé est égal à vrai, n'importez pas si est coché ou non.
@Eliseo le
a déjà un attribut indeterminate
, donc si vous supprimez la directive, cela fonctionne toujours bien.
@DiegoOrtiz, pouvez-vous faire un stackblitz? Je ne peux pas imaginer comment faire sans directive
Oui, vous pouvez utiliser [indeterminate] = "condition"
(sans aucune directive).
Vous ne pouvez pas faire indeterminate = "{{condition}}"
.
La différence est que [...]
définit la propriété de l'élément, alors que sans crochets, vous définissez l'attribut. L'élément HTMLInput a la propriété indeterminate
, mais n'a pas un tel attribut.
Pour utiliser ngModel ou FormControl, qui contient simultanément les états checked
et indeterminate
, vous devez créer une directive personnalisée ou / et une logique supplémentaire dans votre composant principal ( pour référence, voir la réponse de @Eliseo).
Q1. Comment puis-je parcourir ces trois états de la même manière qu'avec Gmail?
Gérer les clics, changer l'état de la paire "cochée" et "indéterminée" en cycle. Exemple avec jQuery .
Q2. Pourquoi est-ce que j'obtiens l'erreur ExpressionChangedAfterItHasBeenCheckedError avec la configuration actuelle?
Vous avez un effet secondaire dans la méthode checkedLabels
, qui change l'état du composant, à chaque fois qu'Angular vérifie la valeur de l'expression [indeterminate] = "checkedLabels ()"
.
Après une longue recherche, je l'ai fait comme ça:
Dans le fichier html:
input[type=checkbox]:checked + b:before { content: "\2713"; font-family: ux-icons; } input[type=checkbox]:indeterminate + b:before { content: "\f067"; font: 14px/1 DXIcons; }
et dans le fichier css:
<input #checkboxes type="checkbox" [checked]="some_condition" [indeterminate]="!some_condition && some_another_condition"> <b class="checkbox-container"></b>
Veuillez remplacer
intermédiaire
parindeterminate
dans votre question.merci @ConnorsFan