如何使用Angular Material <mat-button-toggle>绑定到模型?

时间:2017-11-02 19:25:31

标签: angular angular-material

看看这个Plunker: https://plnkr.co/edit/yu95hUrKlUh4Ttc5SwYD?p=preview

当我使用<mat-slide-toggle>时,我可以修改组件中的值:

<mat-slide-toggle [(ngModel)]="myFlagForSlideToggle">Toggle me!</mat-slide-toggle>

myFlagForSlideToggle按预期更新。

但是当我使用<mat-button-toggle>时,值不会更新。我不得不添加ngDefaultControl来使这个例子工作,但我不确定它是如何重要的。

<mat-button-toggle [(ngModel)]="myFlagForButtonToggle" ngDefaultControl>Toggle me!</mat-button-toggle>

将按钮状态绑定到组件的正确方法是什么?

8 个答案:

答案 0 :(得分:20)

MatButtonToggle组件未实现ControlValueAccessor,因此您无法在其上使用ngModelother purposes引入了ngDefaultControl

MatButtonToggle应该是mat-button-toggle-group的一部分。但是如果你想将它作为一个独立的组件使用并将模型绑定到它,这里有一些如何做到这一点的例子:

<mat-button-toggle 
  [checked]="myFlagForButtonToggle" 
  (change)="myFlagForButtonToggle = $event.source.checked">
    Toggle me!
</mat-button-toggle>

<强> Plunker Example

答案 1 :(得分:6)

mat-button-toggle没有布尔值,[(ngModel)]将无效。请参阅doc

这些切换可以配置为表现为单选按钮或复选框。

用例可能是这样的

<mat-button-toggle-group  [(ngModel)]="myFlagForButtonToggle">
  <mat-button-toggle value="button1"  ngDefaultControl>Toggle me!</mat-button-toggle>
  <mat-button-toggle value="button2"  ngDefaultControl>Toggle me!</mat-button-toggle>
  <mat-button-toggle value="button3"  ngDefaultControl>Toggle me!</mat-button-toggle>
</mat-button-toggle-group>

并将您的布尔值更改为myFlagForButtonToggle :string;

答案 2 :(得分:5)

public selectedVal: string;
constructor() { }

ngOnInit(){
  this.selectedVal ='option1';
} 

public onValChange(val: string) {
  this.selectedVal = val;
}

 <mat-button-toggle-group #group="matButtonToggleGroup" [value]="selectedVal" (change)="onValChange(group.value)" >
  <mat-button-toggle value="option1">
    Option 1
  </mat-button-toggle>
  <mat-button-toggle value="option2">
    Option 2
  </mat-button-toggle>
</mat-button-toggle-group>

答案 3 :(得分:4)

如果您尝试使用mat-button-toggle在启用/禁用某些功能之间进行切换,则必须在mat-button-toggle-group上使用绑定,并确保mat-button-toggle本身具有truefalse的布尔值,而不是字符串值。也就是说:

<mat-button-toggle-group [(ngModel)]="isEnabled">
    <mat-button-toggle [value]="true"> Enable </mat-button-toggle>
    <mat-button-toggle [value]="false"> Disable </mat-button-toggle>
</mat-button-toggle-group>

答案 4 :(得分:2)

我为Angular Material Button Toggle组创建了一个自定义窗体控件。这是我的实现方式:

custom-button-toggle-group.component.html

<mat-button-toggle-group
  (change)="onToggleGroupChange($event)"
  [disabled]=disabled
  [value]=value
>
  <mat-button-toggle
    *ngFor="let toggle of toggles"
    [value]="toggle.value"
  >{{ toggle.label }}</mat-button-toggle>
</mat-button-toggle-group>

custom-button-toggle-group.component.ts

import { Component, forwardRef, HostListener, Input } from '@angular/core';
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';
import { MatButtonToggleChange } from '@angular/material/button-toggle';

export interface ButtonToggle {
  value: string;
  label: string;
}

@Component({
  selector: 'custom-button-toggle-group',
  templateUrl: './button-toggle-group.component.html',
  styleUrls: ['./button-toggle-group.component.scss'],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR, multi: true,
      useExisting: forwardRef(() => CustomButtonToggleGroupComponent),
    }
  ]
})
export class CustomButtonToggleGroupComponent implements ControlValueAccessor {

  @Input() public toggles: ButtonToggle[];

  public value: string;
  public disabled: boolean;

  private onChange: (value: string) => void;
  private onTouched: () => void;


  public onToggleGroupChange({ value }: MatButtonToggleChange): void {
    this.doChange(value);
  }

  writeValue(obj: any): void {
    this.value = obj;
  }

  registerOnChange(fn: any): void {
    this.onChange = fn;
  }

  registerOnTouched(fn: any): void {
    this.onTouched = fn;
  }

  setDisabledState?(isDisabled: boolean): void {
    this.disabled = isDisabled;
  }

  private doChange(selectedValue: string): void {
    this.onChange(selectedValue);
  }

  @HostListener('blur')
  private doBlur(): void {
    this.onTouched();
  }

}

这样,您将可以在FormControl上使用FormControlNamecustom-button-toggle-group等。

答案 5 :(得分:1)

<mat-button-toggle-group formControlName="flags" style="width: 100%" (change)="onChangeFlag($event)">
    <mat-button-toggle *ngFor="let flag of allFlags" value="{{flag.flag}}" style="width: 100%;" 
    matTooltip="{{flag.name}}" [checked]="flagSelected == flag.flag"
    > <img [alt]="flag" src="assets/images/flags/{{flag.flag}}.png" width="20px"/> 
    </mat-button-toggle>

  </mat-button-toggle-group>

答案 6 :(得分:0)

使用 Angular 6.1.3 Angular Material 6.4.6 使用Slide Toggle(即<mat-slide-toggle>

模板

<mat-slide-toggle [checked]="isAwesome"
   (change)="toggleIsAwesome()">
   Is TypeScript Awesome?
</mat-slide-toggle>

组件

export class AwesomeExampleComponent {
   // props
   isAwesome = false;

   // methods
   toggleIsAwesome() {
      this.isAwesome = !this.isAwesome;
      // could put additional logic here
   }
}

我正在使用此解决方案,它很方便地符合Style Guide规则:

  

要做将表示逻辑放在组件类中,而不是模板中。

答案 7 :(得分:0)

我在使用 Angular Material 时遇到了同样的问题。我提供了 name 和 id 属性以及 ngModel 属性(用于模板驱动的表单)以绑定到模型值。它对我有用。

请看下面的代码:

<mat-button-toggle-group name="fontStyle" name="fontStyle" id="fontStyle">
    <mat-button-toggle value="bold">Bold</mat-button-toggle>
    <mat-button-toggle value="italic">Italic</mat-button-toggle>
    <mat-button-toggle value="underline">Underline</mat-button-toggle>