【问题标题】:Mat-checkbox checked not changing checkbox stateMat-checkbox 检查不改变复选框状态
【发布时间】:2018-04-10 08:50:33
【问题描述】:

我正在实现一个显示复选框的语言切换组件,应用程序的每种语言一个复选框(翻译为@ngx-translate)。

点击其中一个复选框时,应用语言会正确切换,但点击的 mat-checkbox 仍未选中。

模板:

<mat-checkbox [checked]="selectedLanguage == 'en'" (click)="switchLanguage('en')">English</mat-checkbox>
<mat-checkbox [checked]="selectedLanguage == 'fr'" (click)="switchLanguage('fr')">French</mat-checkbox>
<mat-checkbox [checked]="selectedLanguage == 'de'" (click)="switchLanguage('de')">German</mat-checkbox>

组件:

export class CheckboxOverviewExample {
  public selectedLanguage: string;

  constructor(){
    this.selectedLanguage = 'fr';
  }

  public switchLanguage(lang: string) {
    this.selectedLanguage = lang;
    // this.translateService.use(lang); // changing ngx-translate language
    console.log('Switched to ' + lang);
  }
}

当您路由到组件时,[checked] 绑定正在工作。登陆组件时确实检查了法语的mat-checkbox(默认值)。现在,当我点击德语或英语时,语言确实会切换,法语复选框会正确取消选中,但是单击的复选框不会选中。

我遗漏了一些东西,可能是一个小细节,但我不明白为什么德语/英语不检查而法语正确地取消检查。

查看this simple stackblitz code 以重现我的情况。

【问题讨论】:

  • 为什么不使用 ngModel 而不是检查?
  • ngModel 应该映射到我没有的布尔值。我有一个language 字段,它可以采用多个字符串值。此外,由于应用程序参数,语言的数量可能会增加(在我的真实代码中,复选框是使用*ngFor 指令呈现的)。
  • 使用单选按钮,这将允许您将语言属性绑定为 ngModel。

标签: angular angular-material angular-material2


【解决方案1】:

所以我有一个答案给你。不需要使用单选按钮,因为您的设计师讨厌它只是使用它

<mat-checkbox [checked]="selectedLanguage === 'en'" (change)="switchLanguage('en')">English</mat-checkbox>
<mat-checkbox [checked]="selectedLanguage === 'fr'" (change)="switchLanguage('fr')">French</mat-checkbox>
<mat-checkbox [checked]="selectedLanguage ==='de'" (change)="switchLanguage('de')">German</mat-checkbox>

也使用selectedLanguage === 'en'检查类型和值

另外,使用(change)="switchLanguage('de') 而不是点击

工作here 或查看this

【讨论】:

  • 您能解释一下(click)(change) 之间的区别吗?它正在工作,但我想了解为什么一个工作而不是另一个工作。据我所知,两者都应该触发变更检测周期。
  • 您也可以检查,在给定的 stackblitz 中,当复选框失去焦点并单击单击方法时会触发使用更改方法,因此如果您使用单击而不是更改,则需要单击元素两次以检查并进入某些浏览器,对用户来说会很困难,所以最好使用更改。
  • 在我的解决方案中,它也可以点击,但您需要双击复选框才能点击
【解决方案2】:

您应该使用 (change) 而不是 (click)。您的模板应更改为:

<mat-checkbox [checked]="selectedLanguage === 'en'" (change)="switchLanguage($event, 'en')">English</mat-checkbox>
<mat-checkbox [checked]="selectedLanguage === 'fr'" (change)="switchLanguage($event, 'fr')">French</mat-checkbox>
<mat-checkbox [checked]="selectedLanguage === 'de'" (change)="switchLanguage($event, 'de')">German</mat-checkbox>

...你的函数将如下所示:

public switchLanguage(event: MatCheckboxChange, lang: string) {
    if(event.checked && this.selectedLanguage!== lang){
        this.selectedLanguage = lang;
        // this.translateService.use(lang); // changing ngx-translate language
        console.log('Switched to ' + lang);
    }
}

记得导入MatCheckboxChange

import { MatCheckboxChange} from '@angular/material';`

链接到Demo


您应该使用radio buttons 来处理此行为。当您只需要允许一个选项选择时,复选框不是正确的方法。

<mat-radio-group [value]="selectedLanguage">
  <mat-radio-button value="en" (click)="switchLanguage('en')">English</mat-radio-button>
  <mat-radio-button value="fr" (click)="switchLanguage('fr')">French</mat-radio-button>
  <mat-radio-button value="de" (click)="switchLanguage('de')">German</mat-radio-button>
</mat-radio-group>

这是StackBlitz Demo

【讨论】:

  • 我理解你的意思,但你没有回答这个问题,这不是我可以/应该使用的另一个组件。我必须使用复选框,因为我们的网页设计师确实在他的应用模型中使用了它。这是一个视觉选择(可能是我们的设计师讨厌收音机)。
  • 你能解释一下(click)(change)之间的区别吗?它正在工作,但我想了解为什么一个工作而不是另一个工作。据我所知,两者都应该触发变更检测周期。
  • 对我来说,用 (change) 更改 (click) 就可以了,谢谢
【解决方案3】:

除了其他答案,您还可以选择不使用单独的函数来处理 change 事件,而是分配如下值: (change)="myBooleanVar = $event.source.checked" 此示例不适用于 OP,但可能对使用复选框分配是/否值的其他人有用。

【讨论】:

    【解决方案4】:

    (click) 是一个 DOM 事件,而 (change) 是从 Angular 框架生成的。

    Click 会有一个通用的 DOM 事件对象,并更改 MatCheckboxChange 对象。

    点击首先触发。

    【讨论】:

      猜你喜欢
      • 2020-01-09
      • 1970-01-01
      • 2016-07-16
      • 2017-08-16
      • 2013-08-30
      • 1970-01-01
      • 2017-03-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多