Enlace de datos bidireccional de casilla de verificación angular 2

203

Soy bastante nuevo en Angular2 y tengo un pequeño problema:

En mi HTML de componente de inicio de sesión, tengo dos casillas de verificación, que deseo vincular de forma bidireccional el enlace de datos con el tipo de componente Componente de inicio de sesión.

Este es el HTML:

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

Y este es el 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 hago clic en una casilla de verificación, obtengo el valor correcto en el controlador (componente).

Pero si cambio el valor de, por ejemplo, saveUsernameen el componente, la casilla de verificación no "obtiene" el nuevo valor.

Así que no puedo manipular la casilla de verificación del Componente (como quiero hacer ngOnIniten el componente.

¡Gracias por tu ayuda!

Junias
fuente
Verifique aquí para ver el ejemplo de Angular 7 de la casilla de verificación freakyjolly.com/…
Code Spy

Respuestas:

353

Puede quitar .selectedde saveUsernameen su entrada de casilla ya saveUsername es un valor lógico. En lugar de [(ngModel)]usar[checked]="saveUsername" (change)="saveUsername = !saveUsername"

Editar: Solución correcta:

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

Actualización: Al igual que @newman notó que cuando ngModelse usa de una forma no funcionará. Sin embargo, debe usar el [ngModelOptions]atributo like (probado en Angular 7):

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

También creé un ejemplo en Stackblitz: https://stackblitz.com/edit/angular-abelrm

hakany
fuente
Si hago esto, aparece un error: Error: ¡No se puede asignar a una referencia o variable!
Junias
hm, ya estoy recibiendo este error: Rechazo de promesa no manejado: ¡No se puede asignar a una referencia o variable! ; Zona: <raíz>; Tarea: Promise.then; Valor: Error: ¡No se puede asignar a una referencia o variable! ¿Y cómo sabe la casilla de verificación si debe activarse / desactivarse? En Angular 1 podría hacerlo así: $scope.loginData = {}; $scope.loginData.username = window.localStorage.getItem("username");y esto en la plantilla:<ion-toggle ng-model="saveUsername" ng-change="toggleSaveUsername()" toggle-class="toggle-energized">Benutzername speichern</ion-toggle>
Junias
1
Por alguna razón, si la entrada no está dentro de un formulario, pero es parte del bucle * ngFor, [(ngModel)]="saveUsername"no funciona, pero este funciona. Debe ser un error en angular?
newman
1
Esto funciona para mí mientras [(ngModel)] se comporta de manera extraña. ¿Alguien puede señalarme alguna documentación o una discusión sobre por qué [marcado] es mejor usar que ngModel en el caso de casillas de verificación?
vc669
3
cuando ngModelse usa de forma no funcionará. [ngModelOptions]="{standalone: true}"es lo que necesitaba
rainversion_3
88

Lamentablemente, la solución proporcionada por @hakani no es un enlace bidireccional . Solo maneja el modelo de cambio unidireccional desde la parte UI / FrontEnd.

En cambio lo simple:

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

hará un enlace bidireccional para la casilla de verificación.

Posteriormente, cuando Model checkboxFlag se cambia de Backend o UI, es decir, checkboxFlag almacena el estado real de la casilla de verificación.

Para estar seguro, he preparado el código Plunker para presentar el resultado: https://plnkr.co/edit/OdEAPWRoqaj0T6Yp0Mfk

Solo para completar esta respuesta, debe incluir la matriz import { FormsModule } from '@angular/forms'into app.module.tsy add to imports, es decir

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

[...]

@NgModule({
  imports: [
    [...]
    FormsModule
  ],
  [...]
})
Ruslan Makrenko
fuente
3
No parece funcionar cuando está usando la casilla de verificación dentro de un ngFor, mientras repite una serie de objetos como[{"checked":true},{"checked":false}]
jackOfAll
No puedo lograr que esta solución funcione, lo entiendocUncaught Error: Template parse errors: Can't bind to 'ngModel' since it isn't a known property of 'input'
sebnukem
55
@sebnukem Parece que falta declarar importación para FormsModule.
teddy
@sebnukem dentro de <input> se requiere una propiedad de nombre para que se use [(ngModel)]
Angela Pan
¿Funcionará también para múltiples casillas de verificación? <input type="checkbox" [(ngModel)]="day.IsChecked" [checked]="day.IsChecked" />
barnes
35

Estoy trabajando con Angular5 y tuve que agregar el atributo "nombre" para que el enlace funcione ... El "id" no es necesario para el enlace.

<input type="checkbox" id="rememberMe" name="rememberMe" [(ngModel)]="rememberMe">
Kris Kilton
fuente
1
Esta respuesta funcionó para mí. Otras respuestas también son correctas. Pero con [(ngModel)] no tenemos que escribir una función separada para cambiar el booleano
Jasmeet
25

Prefiero algo más explícito:

componente.html

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

componente.ts

public saveUsername:boolean;

public onSaveUsernameChanged(value:boolean){
    this.saveUsername = value;
}
MovGP0
fuente
2
Lo único en todo este hilo que funcionó. ¡Gracias! Usando Angular 8.2.11.
Daka
Esta respuesta debería estar en la parte superior.
Harshit Raghav
1
me salvó el día :-)
hannes neukermans
6

Cuando usas <abc [(bar)]="foo"/> sintaxis en angular.

Esto se traduce en: <abc [bar]="foo" (barChange)="foo = $event" />

Lo que significa que su componente debería tener:

@Input() bar;
@Output() barChange = new EventEmitter();
Jose Alberto Fernandez
fuente
la respuesta es muy buena, corta y clara, pero debería ser otra pregunta
Nikita
5

Puede usar algo como esto para tener un enlace de datos bidireccional:

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

Para que funcione la casilla de verificación, debe seguir todos estos pasos:

  1. importar FormsModule en tu módulo
  2. Ponga la entrada dentro de una formetiqueta
  3. su entrada debería ser así:

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

    Nota: no olvide poner nombre en su entrada.

Mahdi Shahbazi
fuente
3

Debe agregar name="selected"atributo al inputelemento.

Por ejemplo:

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

He hecho un componente personalizado probado enlace bidireccional

Mi componente: <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;
}

Lo extraño es que esto funciona

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

mientras esto no

<mycheckbox  [(checked)]="isChecked">
usuario1786641
fuente
1

En cualquier situación, si tiene que vincular un valor con una casilla de verificación que no es booleana, puede probar las siguientes opciones

En el archivo 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>

en el componenteischeckedWithOutBoolean: any = 'Y';

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

Sabbir
fuente
1

Sé que puede ser una respuesta repetida, pero para cualquiera que quiera cargar la lista de casillas de verificación con la casilla de verificación selectall en forma angular, sigo este ejemplo: Seleccione todas / deseleccione todas las casillas usando angular 2+

funciona bien pero solo necesita agregar

[ngModelOptions]="{standalone: true}" 

El HTML final debería ser así:

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

Mecanografiado

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

espero que esto ayude gracias

taha mosaad
fuente
0

Una solución alternativa para lograr lo mismo, especialmente si desea utilizar la casilla de verificación con el bucle for, es almacenar el estado de la casilla de verificación dentro de una matriz y cambiarlo según el índice del *ngForbucle. De esta manera, puede cambiar el estado de la casilla de verificación en su 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;
    }
  }
Sid
fuente
0

Mi directiva angular como 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
fuente
Hola, explique su problema, ¿qué ha intentado y agregue algo de contexto a su pregunta
538ROMEO
0

En la casilla de verificación p angular,

Utilice todos los atributos de la casilla de verificación p

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

Y lo que es más importante, no olvide incluirlo [ngModelOptions]="{standalone: true}, ya que AHORRÓ MI DÍA.

Mian Taimoor Tahir
fuente
0
Angular: "9.0.0"
Angular CLI: 9.0.1
Node: 13.10.1
OS: linux x64

archivo .html

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

archivo .ts

userConsent: boolean = false;
khizer
fuente