html - ngModel 不适用于 ngFor 内的输入类型复选框

标签 html typescript angular7

在 ngFor 中使用复选框时,ngModal 似乎不起作用,而 重复对象数组,例如

[{"checked":true},{"checked":false}]

如果我们将组件中的 selected 属性更改为 true 或 false,它不会反射(reflect)在 UI 中,相同的逻辑将适用于 md bootstrap 的 mdb-checkbox。

app.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  sampleObj = [
    {'checked': false, name: 'option 1'},
    {'checked': false, name: 'option 2'},
    {'checked': false, name: 'option 3'},
    {'checked': true, name: 'option 4'}
  ];

  sampleFunc(event, i) {
    if (event.currentTarget.checked) {
      alert(i);
      this.sampleObj[i].checked = false;
    }
  }
}

app.component.html

  <div *ngFor="let item of sampleObj; let i = index">
  <input type='checkbox' name='item{{i}}' [(ngModel)]="item.checked" (change)="sampleFunc($event, i)" /> 
  <label for='item{{i}}'><span>{{item.name}}</span></label>

</div>

工作示例 https://stackblitz.com/edit/angular-3orv4w

角度版本:

   Angular CLI: 7.1.1
Node: 10.14.2
OS: win32 x64
Angular: 7.1.1
... animations, cdk, cli, common, compiler, compiler-cli, core
... forms, language-service, material, platform-browser
... platform-browser-dynamic, router

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.11.1
@angular-devkit/build-angular     0.12.1
@angular-devkit/build-optimizer   0.12.1
@angular-devkit/build-webpack     0.12.1
@angular-devkit/core              7.1.1
@angular-devkit/schematics        7.1.1
@angular/pwa                      0.11.2
@angular/service-worker           7.1.2
@ngtools/webpack                  7.2.1
@schematics/angular               7.1.1
@schematics/update                0.11.1
rxjs                              6.3.3
typescript                        3.1.6
webpack                           4.23.1

最佳答案

好的,就到这里吧。这是您修改并注释的 stackblitz-class。

为了实现您的目标,您可以做的就是暂时记住当前单击的复选框的索引。我使用变量marker 来完成此操作。

我几乎不建议在开始操作该框之前等待 ngAfterViewChecked()-hook,因为这样您可以确保在以下情况下不会遇到任何计时问题:页面有时会变慢。

下一步是检查标记是否已设置。然后你必须将实际的切换回代码包装到超时函数中。如果不这样做,您将遇到此错误:

ExpressionChangedAfterItHasBeenCheckedError:表达式在检查后已更改。先前值:“模型:true”。当前值:“型号:false”。

就是这样。

您可以尝试进一步减少超时,以使复选框不会闪烁。但请始终注意,如果您行动太快,可能会遇到上述错误。

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {

  // the clicked checkbox's index
  private marker: number = -1;

  sampleObj = [
    {'checked': false, name: 'option 1'},
    {'checked': false, name: 'option 2'},
    {'checked': false, name: 'option 3'},
    {'checked': true, name: 'option 4'}
  ];

  sampleFunc(event, i) {
    if (event.currentTarget.checked) {
      // memorize the clicked checkbox's index
      this.marker = i;
    }
  }

  toggle() : void {
    this.sampleObj[1].checked = !this.sampleObj[1].checked; 
  }

  ngAfterViewChecked(): void {
    // if a marker is set
    if (this.marker > -1) {
      // start the timeout and then reset the checkbox
      setTimeout (() => {
      this.sampleObj[this.marker].checked = !this.sampleObj[this.marker].checked;
      this.marker = -1;
      }, 20);
    }
  }
}

关于html - ngModel 不适用于 ngFor 内的输入类型复选框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54250115/

相关文章:

jquery - 检测何时播放或结束音频文件

typescript - 使用 TypeScript 的 Jest 测试无法识别导入别名

reactjs - react native 和 typescript 多内联样式

html - 表中的 Jquery 移动 UI 输入下拉格式化行为

javascript - 全屏期间媒体查询与伪类 - CSS 样式顺序?

html - 线不会因 Angular 而中断\n

angular - 在 Angular 7( typescript 3.1.3)中找不到名称 'require'

javascript - 选中复选框时如何突出显示表格行? Angular 7

javascript - 直接以 Angular 更改构建文件是一个好习惯吗?

JavaScript FancyTree : is it possible to distinguish between the selection of a node and the action of expanding it.