Liaison de données bidirectionnelle avec case à cocher angulaire 2


203

Je suis assez nouveau sur Angular2 et j'ai un petit problème:

Dans mon Login-Component-HTML, j'ai deux cases à cocher, que je veux lier de manière bidirectionnelle aux données au Login-Component-TypeScript.

Voici le HTML:

<div class="checkbox">
<label>
    <input #saveUsername [(ngModel)]="saveUsername.selected" type="checkbox" data-toggle="toggle">Save username
</label>
</div>

Et voici le Component.ts:

import { Component, OnInit }    from '@angular/core';
import { Router }               from '@angular/router';
import { Variables }            from '../../services/variables';

@Component({
    selector: 'login',
    moduleId: module.id,
    templateUrl: 'login.component.html',
    styleUrls: ['login.component.css']
})


export class LoginComponent implements OnInit {

    private saveUsername: boolean = true;
    private autoLogin: boolean = true;
    constructor(private router: Router, private variables: Variables) { }

    ngOnInit() { 
        this.loginValid = false;
        // Get user name from local storage if you want to save

        if (window.localStorage.getItem("username") === null) {
           this.saveUsername = true;
           this.autoLogin = true;
           console.log(this.saveUsername, this.autoLogin);
        } else {
           console.log("init", window.localStorage.getItem("username"));
        }
    }

    login(username: string, password: string, saveUsername: boolean, autoLogin: boolean) {
        this.variables.setUsername(username);
        this.variables.setPassword(password);
        this.variables.setIsLoggedIn(true);
        console.log(saveUsername, autoLogin);
        //this.router.navigate(['dashboard']);
    }

Si je clique sur une case à cocher, j'obtiens la valeur correcte dans le contrôleur (composant).

Mais si je change la valeur de par exemple saveUsernamedans le composant, la case à cocher n'a pas "obtenu" la nouvelle valeur.

Je ne peux donc pas manipuler la case du composant (comme je veux le faire ngOnInitdans le composant).

Merci de votre aide!


Cliquez ici pour voir l'exemple Angular 7 de liaison de case à cocher freakyjolly.com/…
Code Spy

Réponses:


353

Vous pouvez supprimer .selectedde saveUsernamedans votre entrée de case à cocher car saveUsername est un booléen. Au lieu d' [(ngModel)]utilisation[checked]="saveUsername" (change)="saveUsername = !saveUsername"

Edit: Solution correcte:

<input
  type="checkbox"
  [checked]="saveUsername"
  (change)="saveUsername = !saveUsername"/>

Mise à jour: Comme @newman l'a remarqué lorsqu'il ngModelest utilisé dans un formulaire, cela ne fonctionnera pas. Cependant, vous devez utiliser un [ngModelOptions]attribut comme (testé dans Angular 7):

<input
  type="checkbox"
  [(ngModel)]="saveUsername"
  [ngModelOptions]="{standalone: true}"/> `

J'ai également créé un exemple sur Stackblitz: https://stackblitz.com/edit/angular-abelrm


Si je fais cela, alors j'obtiens une erreur: Erreur: Impossible d'assigner à une référence ou une variable!
Junias

hm, je reçois déjà cette erreur: rejet de la promesse non gérée: impossible à affecter à une référence ou une variable! ; Zone: <racine>; Tâche: Promise.then; Valeur: Erreur: impossible d'affecter à une référence ou une variable! Et comment la case à cocher sait-elle si elle doit être activée / désactivée? Dans Angular 1, je pourrais le faire comme ceci: $scope.loginData = {}; $scope.loginData.username = window.localStorage.getItem("username");et ceci dans le modèle:<ion-toggle ng-model="saveUsername" ng-change="toggleSaveUsername()" toggle-class="toggle-energized">Benutzername speichern</ion-toggle>
Junias

1
Pour certaines raisons, si l'entrée n'est pas à l'intérieur d'un formulaire, mais qu'elle fait partie de la boucle * ngFor, [(ngModel)]="saveUsername"ne fonctionne pas, mais celle-ci fonctionne. Ça doit être un bug en angulaire?
newman

1
Cela fonctionne pour moi pendant que [(ngModel)] se comporte bizarrement. Quelqu'un peut-il m'indiquer une documentation ou une discussion sur la raison pour laquelle [vérifié] est préférable d'utiliser que ngModel dans le cas des cases à cocher?
vc669

3
quand ngModelest utilisé dans un formulaire, cela ne fonctionnera pas. [ngModelOptions]="{standalone: true}"c'est ce dont j'avais besoin.
rainversion_3

88

Malheureusement, la solution fournie par @hakani n'est pas contraignante dans les deux sens . Il gère simplement le modèle de changement à sens unique de la partie UI / FrontEnd.

Au lieu de cela, le simple:

<input [(ngModel)]="checkboxFlag" type="checkbox"/>

fera une liaison bidirectionnelle pour la case à cocher.

Ensuite, lorsque la case à cocher Modèle est changé de Backend ou UI part - voila, checkboxFlag stocke l'état réel de la case à cocher.

Pour être sûr d'avoir préparé le code Plunker pour présenter le résultat: https://plnkr.co/edit/OdEAPWRoqaj0T6Yp0Mfk

Juste pour compléter cette réponse, vous devez inclure le tableau import { FormsModule } from '@angular/forms'dans app.module.tset ajouter au tableau des importations, c.-à-d.

import { FormsModule } from '@angular/forms';

[...]

@NgModule({
  imports: [
    [...]
    FormsModule
  ],
  [...]
})

3
Ne semble pas fonctionner lorsque vous utilisez la case à cocher dans un ngFor, tout en répétant un tableau d'objets comme[{"checked":true},{"checked":false}]
jackOfAll

Je ne peux pas faire fonctionner cette solution, je reçoiscUncaught Error: Template parse errors: Can't bind to 'ngModel' since it isn't a known property of 'input'
sebnukem

5
@sebnukem Il semble que vous manquiez de déclarer l'importation pour FormsModule.
teddy

@sebnukem dans <input> une propriété de nom est requise pour [(ngModel)] à utiliser
Angela Pan

Cela fonctionnera-t-il également pour plusieurs cases à cocher? <input type="checkbox" [(ngModel)]="day.IsChecked" [checked]="day.IsChecked" />
barnes

35

Je travaille avec Angular5 et j'ai dû ajouter l'attribut "name" pour que la liaison fonctionne ... "L'id" n'est pas requis pour la liaison.

<input type="checkbox" id="rememberMe" name="rememberMe" [(ngModel)]="rememberMe">

1
Cette réponse a fonctionné pour moi. D'autres réponses sont également correctes. Mais avec [(ngModel)] nous n'avons pas besoin d'écrire une fonction distincte pour changer le booléen
Jasmeet

25

Je préfère quelque chose de plus explicite:

component.html

<input #saveUserNameCheckBox
    id="saveUserNameCheckBox" 
    type="checkbox" 
    [checked]="saveUsername" 
    (change)="onSaveUsernameChanged(saveUserNameCheckBox.checked)" />

component.ts

public saveUsername:boolean;

public onSaveUsernameChanged(value:boolean){
    this.saveUsername = value;
}

2
La seule chose dans tout ce fil qui a fonctionné. Je vous remercie! Utilisation angulaire 8.2.11.
daka

Cette réponse devrait être au top.
harshit raghav

1
sauvé ma journée :-)
hannes neukermans

6

Lors de l'utilisation <abc [(bar)]="foo"/> syntaxe sur angulaire.

Cela se traduit par: <abc [bar]="foo" (barChange)="foo = $event" />

Ce qui signifie que votre composant devrait avoir:

@Input() bar;
@Output() barChange = new EventEmitter();

la réponse est vraiment bien - courte et claire, mais devrait sous une autre question
Nikita

5

Vous pouvez simplement utiliser quelque chose comme ça pour avoir une liaison de données bidirectionnelle:

<input type="checkbox" [checked]="model.property" (change)="model.property = !model.consent_obtained_ind">

3

Pour que la case à cocher fonctionne, vous devez suivre toutes ces étapes:

  1. importer FormsModule dans votre module
  2. Mettez l'entrée dans une formbalise
  3. votre entrée devrait être comme ceci:

    <input name="mpf" type="checkbox" [(ngModel)]="value" />

    Remarque: n'oubliez pas de mettre un nom dans votre entrée.


3

Vous devez ajouter un name="selected"attribut à l' inputélément.

Par exemple:

<div class="checkbox">
  <label>
    <input name="selected" [(ngModel)]="saveUsername.selected" type="checkbox">Save username
  </label>
</div>

2

J'ai fait un composant personnalisé essayé la liaison bidirectionnelle

Mon composant: <input type="checkbox" [(ngModel)]="model" >

_model:  boolean;   

@Output() checked: EventEmitter<boolean> = new EventEmitter<boolean>();

@Input('checked')
set model(checked: boolean) {

  this._model = checked;
  this.checked.emit(this._model);
  console.log('@Input(setmodel'+checked);
}

get model() {
  return this._model;
}

chose étrange est que cela fonctionne

<mycheckbox  [checked]="isChecked" (checked)="isChecked = $event">

alors que ce n'est pas

<mycheckbox  [(checked)]="isChecked">

1

Dans toutes les situations, si vous devez lier une valeur avec une case à cocher qui n'est pas booléenne, vous pouvez essayer les options ci-dessous

Dans le fichier Html:

<div class="checkbox">
<label for="favorite-animal">Without boolean Value</label>
<input type="checkbox" value="" [checked]="ischeckedWithOutBoolean == 'Y'" 
(change)="ischeckedWithOutBoolean = $event.target.checked ? 'Y': 'N'">
</div>

dans le composantischeckedWithOutBoolean: any = 'Y';

Voir dans le stackblitz https://stackblitz.com/edit/angular-5szclb?embed=1&file=src/app/app.component.html


1

Je sais que la réponse peut être répétée, mais pour tous ceux qui veulent charger la liste des cases à cocher avec la case à cocher selectall sous forme angulaire, je suis cet exemple: Tout sélectionner / désélectionner toutes les cases à cocher en utilisant angulaire 2+

ça marche bien mais juste besoin d'ajouter

[ngModelOptions]="{standalone: true}" 

le HTML final devrait être comme ceci:

<ul>
    <li><input type="checkbox" [(ngModel)]="selectedAll" (change)="selectAll();"/></li>
    <li *ngFor="let n of names">
    <input type="checkbox" [(ngModel)]="n.selected" (change)="checkIfAllSelected();">{{n.name}}
    </li>
  </ul>

Manuscrit

  selectAll() {
    for (var i = 0; i < this.names.length; i++) {
      this.names[i].selected = this.selectedAll;
    }
  }
  checkIfAllSelected() {
    this.selectedAll = this.names.every(function(item:any) {
        return item.selected == true;
      })
  }

j'espère que cette aide thnx


0

Une solution de contournement pour obtenir la même chose spécialement si vous souhaitez utiliser la case à cocher avec pour la boucle est de stocker l'état de la case à cocher dans un tableau et de le modifier en fonction de l'index de la *ngForboucle. De cette façon, vous pouvez modifier l'état de la case à cocher dans votre composant.

app.component.html

<div *ngFor="let item of items; index as i"> <input type="checkbox" [checked]="category[i]" (change)="checkChange(i)"> {{item.name}} </div>

app.component.ts

items = [
    {'name':'salad'},
    {'name':'juice'},
    {'name':'dessert'},
    {'name':'combo'}
  ];

  category= []

  checkChange(i){
    if (this.category[i]){  
      this.category[i] = !this.category[i];
    }
    else{
      this.category[i] = true;
    }
  }

0

Ma directive angulaire comme angularjs (ng-true-value ng-false-value)

@Directive({
    selector: 'input[type=checkbox][checkModel]'
})
export class checkboxDirective {
    @Input() checkModel:any;
    @Input() trueValue:any;
    @Input() falseValue:any;
    @Output() checkModelChange = new EventEmitter<any>();

    constructor(private el: ElementRef) { }

    ngOnInit() {
       this.el.nativeElement.checked = this.checkModel==this.trueValue;
    }

    @HostListener('change', ['$event']) onChange(event:any) {
        this.checkModel = event.target.checked ? this.trueValue : this.falseValue;
        this.checkModelChange.emit(this.checkModel);
    }

}

html

<input type="checkbox" [(checkModel)]="check" [trueValue]="1" [falseValue]="0">

Bonjour, veuillez expliquer votre problème, qu'avez-vous essayé et ajoutez un peu de contexte à votre question
538ROMEO

0

Dans la case P angulaire,

Utiliser tous les attributs de p-checkbox

<p-checkbox name="checkbox" value="isAC" 
    label="All Colors" [(ngModel)]="selectedAllColors" 
    [ngModelOptions]="{standalone: true}" id="al" 
    binary="true">
</p-checkbox>

Et surtout, n'oubliez pas d'inclure [ngModelOptions]="{standalone: true}aussi bien que cela a sauvé ma journée.


0
Angular: "9.0.0"
Angular CLI: 9.0.1
Node: 13.10.1
OS: linux x64

fichier .html

<input [(ngModel)]="userConsent" id="userConsent" required type="checkbox"/> " I Accept"

fichier .ts

userConsent: boolean = false;
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.