How to bind to model with Angular Material ?

2020-02-04 15:26发布

问题:

Take a look at this Plunker: https://plnkr.co/edit/yu95hUrKlUh4Ttc5SwYD?p=preview

When I'm using <mat-slide-toggle>, I am able to modify the values in my component:

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

myFlagForSlideToggle is updated as expected.

But when I'm using <mat-button-toggle>, the values are not updated. I had to add ngDefaultControl to even make this example work, but I'm not sure how it matters.

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

What is the correct way to bind a button state to the component?

回答1:

MatButtonToggle component doesn't implement ControlValueAccessor therefore you can't use ngModel on it. ngDefaultControl was introduced for other purposes.

MatButtonToggle is supposed to be a part of mat-button-toggle-group. But if you want to use it as a standalone component and bind model to it here is some example of how you can do it:

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

Plunker Example



回答2:

mat-button-toggle dont have a boolean value and [(ngModel)] won't work. See doc.

These toggles can be configured to behave as either radio-buttons or checkboxes.

a use case may be like this

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

and change your boolean to myFlagForButtonToggle :string;



回答3:

If you are trying to use mat-button-toggle to switch between enabling / disabling something, you will have to use a binding on mat-button-toggle-group, and make sure that the mat-button-toggle's themselves have the boolean values of true and false, not the string values. That is to say:

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

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>


回答5:

With Angular 6.1.3 and Angular Material 6.4.6 using Slide Toggle (i.e., <mat-slide-toggle>)

Template

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

Component

export class AwesomeExampleComponent {
   // props
   isAwesome = false;

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

I'm using this solution, and it conveniently aligns with the Style Guide rule:

Do put presentation logic in the component class, and not in the template.