Casella di controllo Angolare 2 Binding dati bidirezionale


203

Sono abbastanza nuovo su Angular2 e ho un piccolo problema:

Nel mio Login-Component-HTML, ho due caselle di controllo, che voglio associare in modo bidirezionale ai dati di Login-Component-TypeScript.

Questo è l'HTML:

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

E questo è il 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']);
    }

Se faccio clic su una casella di controllo, ottengo il valore corretto nel controller (componente).

Ma se cambio il valore, ad esempio, saveUsernamenel componente, la casella di controllo non "ottiene" il nuovo valore.

Quindi non posso manipolare la casella di controllo dal Componente (come voglio fare nel ngOnInitnel componente.

Grazie per l'aiuto!


Controlla qui per esempio Angular 7 di rilegatura checkbox freakyjolly.com/…
Codice spia

Risposte:


353

Puoi rimuovere .selectedda saveUsernamenella casella di controllo in quanto saveUsername è un valore booleano. Invece di [(ngModel)]usare[checked]="saveUsername" (change)="saveUsername = !saveUsername"

Modifica: soluzione corretta:

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

Aggiornamento: come notato da @newman quando ngModelviene utilizzato in un modulo, non funzionerà. Tuttavia, dovresti usare l' [ngModelOptions]attributo like (testato in Angular 7):

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

Ho anche creato un esempio su Stackblitz: https://stackblitz.com/edit/angular-abelrm


Se lo faccio, ricevo un errore: Errore: impossibile assegnare un riferimento o una variabile!
Junias,

hm, sto già ricevendo questo errore: Non gestito Rifiuto promessa: impossibile assegnare a un riferimento o una variabile! ; Zona: <root>; Compito: Promise.then; Valore: errore: impossibile assegnare a un riferimento o una variabile! E come fa a sapere la casella di controllo, se deve essere attivata / disattivata? In Angular 1 potrei farlo in questo modo: $scope.loginData = {}; $scope.loginData.username = window.localStorage.getItem("username");e questo nel modello:<ion-toggle ng-model="saveUsername" ng-change="toggleSaveUsername()" toggle-class="toggle-energized">Benutzername speichern</ion-toggle>
Junias,

1
Per alcuni motivi, se l'input non è all'interno di un modulo, ma fa parte del ciclo * ngFor, [(ngModel)]="saveUsername"non funziona, ma funziona. Deve essere un bug in angolare?
Newman,

1
Questo funziona per me mentre [(ngModel)] si comporta in modo strano. Qualcuno può indicarmi un po 'di documentazione o una discussione sul perché [controllato] è meglio usare di ngModel nel caso delle caselle di controllo?
vc669

3
quando ngModelviene utilizzato in un modulo non funzionerà. [ngModelOptions]="{standalone: true}"è quello di cui avevo bisogno.
rainversion_3

88

Sfortunatamente la soluzione fornita da @hakani non è vincolante a due vie . Gestisce solo il modello che cambia unidirezionale dalla parte UI / FrontEnd.

Invece il semplice:

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

eseguirà l'associazione bidirezionale per la casella di controllo.

Successivamente, quando Model checkboxFlag viene modificato dalla parte Backend o UI - voilà, checkboxFlag memorizza lo stato attuale della casella di controllo.

Per essere sicuro di aver preparato il codice Plunker per presentare il risultato: https://plnkr.co/edit/OdEAPWRoqaj0T6Yp0Mfk

Solo per completare questa risposta dovresti includere l' array import { FormsModule } from '@angular/forms'in app.module.tse aggiungere ad Import, ad es

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

[...]

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

3
Non sembra funzionare quando si utilizza la casella di controllo all'interno di un ngFor, mentre si ripete una serie di oggetti come[{"checked":true},{"checked":false}]
jackOfAll

Non riesco a far funzionare questa soluzione, ottengocUncaught Error: Template parse errors: Can't bind to 'ngModel' since it isn't a known property of 'input'
sebnukem il

5
@sebnukem Sembra che manchi dichiarare l'importazione per FormsModule.
teddy

@sebnukem all'interno di <input> è necessaria una proprietà name per [(ngModel)] da utilizzare
Angela Pan

Funzionerà anche per più caselle di controllo? <input type="checkbox" [(ngModel)]="day.IsChecked" [checked]="day.IsChecked" />
barnes,

35

Sto lavorando con Angular5 e ho dovuto aggiungere l'attributo "name" per far funzionare il binding ... "id" non è richiesto per il binding.

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

1
Questa risposta ha funzionato per me. Anche altre risposte sono corrette. Ma con [(ngModel)] non dobbiamo scrivere una funzione separata per cambiare il valore booleano
Jasmeet

25

Preferisco qualcosa di più esplicito:

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
L'unica cosa in tutto questo thread che ha funzionato. Grazie! Usando angolare 8.2.11.
daka,

Questa risposta dovrebbe essere in cima.
harshit raghav,

1
mi ha salvato la giornata :-)
hannes neukermans

6

Quando si utilizza la <abc [(bar)]="foo"/>sintassi su angolare.

Questo si traduce in: <abc [bar]="foo" (barChange)="foo = $event" />

Ciò significa che il componente dovrebbe avere:

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

la risposta è davvero buona - breve e chiara, ma dovrebbe sotto un'altra domanda
Nikita

5

Puoi semplicemente usare qualcosa del genere per avere un'associazione dati bidirezionale:

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

3

Per far funzionare la casella di controllo è necessario seguire tutti questi passaggi:

  1. importare FormsModule nel tuo modulo
  2. Inserisci l'input all'interno di un formtag
  3. il tuo contributo dovrebbe essere così:

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

    Nota: non dimenticare di inserire il nome nel tuo input.


3

Devi aggiungere l' name="selected"attributo inputall'elemento.

Per esempio:

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

2

Ho fatto un componente personalizzato provato a legare in due modi

myComponent: <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;
}

cosa strana è che funziona

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

mentre questo non lo farà

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

1

In ogni caso, se devi associare un valore a una casella di controllo non booleana, puoi provare le opzioni seguenti

Nel file 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>

nel componenteischeckedWithOutBoolean: any = 'Y';

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


1

So che può essere una risposta ripetuta ma per chiunque voglia caricare l'elenco di caselle di controllo con la casella di controllo selectall in forma angolare, seguo questo esempio: Seleziona tutto / deseleziona tutto la casella di controllo utilizzando angolare 2+

funziona benissimo ma devo solo aggiungere

[ngModelOptions]="{standalone: true}" 

l' HTML finale dovrebbe essere così:

<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>

Dattiloscritto

  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;
      })
  }

spero che questo aiuto grazie


0

Una soluzione alternativa per ottenere lo stesso specialmente se si desidera utilizzare la casella di controllo con for loop consiste nel memorizzare lo stato della casella di controllo in un array e modificarlo in base all'indice del *ngForloop. In questo modo è possibile modificare lo stato della casella di controllo nel componente.

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

La mia direttiva angolare come 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">

Ciao, per favore, spiega il tuo problema, cosa hai provato e aggiungi un po 'di contesto alla tua domanda
538ROMEO,

0

Nella casella di controllo Angolare p,

Usa tutti gli attributi di p-checkbox

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

E, soprattutto, non dimenticare di includere [ngModelOptions]="{standalone: true}oltre a SALVATO IL MIO GIORNO.


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

file .html

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

file .ts

userConsent: boolean = false;
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.