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!

Junias
la source
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

hakany
la source
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
  ],
  [...]
})
Ruslan Makrenko
la source
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">
Kris Kilton
la source
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;
}
MovGP0
la source
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();
Jose Alberto Fernandez
la source
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">
Nuno Ferro
la source
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.

Mahdi Shahbazi
la source
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>
M.Shakeri
la source
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">
user1786641
la source
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

Sabbir
la source
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

taha mosaad
la source
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;
    }
  }
Sid
la source
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">
Edgardo Rivera
la source
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.

Mian Taimoor Tahir
la source
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;
Khizer
la source