Angular 2复选框双向数据绑定

Posted

技术标签:

【中文标题】Angular 2复选框双向数据绑定【英文标题】:Angular 2 Checkbox Two Way Data Binding 【发布时间】:2017-03-06 00:12:28 【问题描述】:

我对 Angular2 还很陌生,但我有一个小问题:

在我的 Login-Component-html 中,我有两个复选框,我想以两种方式将它们绑定到 Login-Component-TypeScript。

这是 HTML:

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

这是 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']);
    

如果我点击一个复选框,我会在控制器(组件)中得到正确的值。

但如果我在组件中更改例如 saveUsername 的值,复选框不会“获取”新值。

所以我不能从组件中操作复选框(就像我想在组件中的 ngOnInit 中做的那样。

感谢您的帮助!

【问题讨论】:

【参考方案1】:
Angular: "9.0.0"
Angular CLI: 9.0.1
Node: 13.10.1
OS: linux x64

.html 文件

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

.ts 文件

userConsent: boolean = false;

【讨论】:

【参考方案2】:

我知道可能会重复回答 但是对于任何想要将带有全选复选框的复选框列表加载为角度形式的人,我都遵循以下示例: Select all/deselect all checkbox using angular 2+

它工作正常,但只需要添加

[ngModelOptions]="standalone: true" 

最后的HTML应该是这样的:

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

TypeScript

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

希望对您有所帮助 谢谢

【讨论】:

【参考方案3】:

在 Angular p-checkbox 中,

使用p-checkbox的所有属性

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

更重要的是,不要忘记包含[ngModelOptions]="standalone: true 以及它拯救了我的一天。

【讨论】:

【参考方案4】:

我的 angular 指令如 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">

【讨论】:

您好,请解释您的问题,您尝试了什么,并为您的问题添加一些上下文【参考方案5】:

如果您想将复选框与 for 循环一起使用,实现相同目的的解决方法是将复选框的状态存储在数组中,并根据 *ngFor 循环的索引对其进行更改。这样您就可以更改组件中复选框的状态。

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;
    
  

【讨论】:

【参考方案6】:

您可以在复选框输入中从 saveUsername 中删除 .selected,因为 saveUsername 是一个布尔值。而不是[(ngModel)] 使用[checked]="saveUsername" (change)="saveUsername = !saveUsername"

编辑:正确的解决方案:

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

更新: 就像@newman 注意到的,当ngModel 以一种不起作用的形式使用时。但是,您应该使用 [ngModelOptions] 属性,例如(在 Angular 7 中测试):

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

我还在 Stackblitz 创建了一个示例:https://stackblitz.com/edit/angular-abelrm

【讨论】:

如果我这样做,我会得到一个错误:错误:无法分配给引用或变量! 由于某些原因,如果输入不在表单内,但它是 *ngFor 循环的一部分,[(ngModel)]="saveUsername" 不起作用,但这个有效。一定是 Angular 的 bug? 这对我有用,而 [(ngModel)] 的行为很奇怪。有人可以向我指出一些文档或讨论为什么在复选框的情况下 [checked] 比 ngModel 更好用? 虽然这是公认的答案,但它在某些情况下不起作用,除非有“名称”属性。显然是任何名字。 ngModel 以某种形式使用时,它将不起作用。 [ngModelOptions]="standalone: true" 是我需要的。【参考方案7】:

在任何情况下,如果您必须将值与非布尔型复选框绑定,那么您可以尝试以下选项

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

在组件中ischeckedWithOutBoolean: any = 'Y';

在 stackblitz 中查看 https://stackblitz.com/edit/angular-5szclb?embed=1&file=src/app/app.component.html

【讨论】:

【参考方案8】:

你可以使用这样的东西来进行两种数据绑定:

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

【讨论】:

【参考方案9】:

您必须将name="selected" 属性添加到input 元素。

例如:

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

【讨论】:

【参考方案10】:

我正在使用 Angular5,我必须添加“名称”属性才能使绑定工作......绑定不需要“id”。

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

【讨论】:

这个答案对我有用。其他答案也是正确的。但是使用 [(ngModel)] 我们不必编写单独的函数来切换布尔值【参考方案11】:

我做了一个自定义组件尝试了两种方式绑定

我的组件: &lt;input type="checkbox" [(ngModel)]="model" &gt;

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

奇怪的是这行得通

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

虽然这不会

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

【讨论】:

【参考方案12】:

很遗憾,@hakani 提供的解决方案不是双向绑定。它只处理 UI/FrontEnd 部分的单向更改模型。

取而代之的是简单的:

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

将对复选框进行双向绑定。

之后,当模型 checkboxFlag 从后端或 UI 部分更改时 - 瞧,checkboxFlag 存储实际的复选框状态。

为了确保我已经准备好 Plunker 代码来呈现结果:https://plnkr.co/edit/OdEAPWRoqaj0T6Yp0Mfk

为了完成这个答案,您应该将import FormsModule from '@angular/forms' 包含到app.module.ts 中并添加到导入数组中,即

import  FormsModule  from '@angular/forms';

[...]

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

【讨论】:

当您在 ngFor 中使用复选框时似乎不起作用,同时重复像 ["checked":true,"checked":false] 这样的对象数组 我无法使用此解决方案,我收到了cUncaught Error: Template parse errors: Can't bind to 'ngModel' since it isn't a known property of 'input' @sebnukem 您似乎缺少为 FormsModule 声明导入。 @sebnukem inside 需要 name 属性才能使用 [(ngModel)] 如果在*ngFor 中使用,name 属性对于循环中的每个项目必须是唯一的。因此,我遇到了默认选中状态的问题,一旦我将 name 属性设为唯一,默认选中状态就会按预期工作。【参考方案13】:

要使复选框起作用,您应该遵循所有这些步骤:

    在你的模块中导入FormsModule 将输入放在form 标签内

    你的输入应该是这样的:

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

    注意:不要忘记在输入中输入姓名。

【讨论】:

【参考方案14】:

在 Angular 上使用 &lt;abc [(bar)]="foo"/&gt; 语法时。

这转化为: &lt;abc [bar]="foo" (barChange)="foo = $event" /&gt;

这意味着你的组件应该有:

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

【讨论】:

答案非常好 - 简短明了,但应该在另一个问题下【参考方案15】:

我更喜欢更明确的东西:

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;

【讨论】:

整个线程中唯一有效的东西。谢谢!使用 Angular 8.2.11. 这个答案应该在上面。 拯救了我的一天 :-)

以上是关于Angular 2复选框双向数据绑定的主要内容,如果未能解决你的问题,请参考以下文章

angular入门篇(2)——*ngIf,数据绑定事件,属性绑定

Angular 手动实现ngModal数据双向绑定

Angular JS - 3 - Angular JS 双向数据绑定

如何在 Angular -2/4 中删除双向数据绑定

angular双向绑定

输入复选框元素的双向数据绑定