Tom*_*all 8 typescript angular-material angular
我是Angular和Angular Material的新手,现在我在一些项目中担任支持.有一个带过滤器和一个复选框的网格,用于检查网格中的用户是处于活动状态,非活动状态还是未选择状态.只有两个选项(活动,非活动)会更简单,但是,我必须为它制作3个状态:
以下是官方Angular Material文档中的复选框示例:https://stackblitz.com/angular/rxdmnbxmkgk? file = app%2Fcheckbox-configurable- example.html
如何以最简单的方式制作它?
smn*_*brv 10
TL; DR
这是一个使用以下解决方案的现成组件:
import { Component, forwardRef, OnInit } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { MAT_CHECKBOX_CLICK_ACTION } from '@angular/material';
@Component({
selector: 'app-tri-state-checkbox',
templateUrl: './tri-state-checkbox.component.html',
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => TriStateCheckboxComponent),
multi: true,
},
{ provide: MAT_CHECKBOX_CLICK_ACTION, useValue: 'noop' },
],
})
export class TriStateCheckboxComponent implements ControlValueAccessor {
tape = [null, true, false];
value: boolean;
disabled: boolean;
private onChange: (val: boolean) => void;
private onTouched: () => void;
writeValue(value: boolean) {
this.value = value;
}
setDisabledState(disabled: boolean) {
this.disabled = disabled;
}
next() {
this.onChange(this.value = this.tape[(this.tape.indexOf(this.value) + 1) % this.tape.length]);
this.onTouched();
}
registerOnChange(fn: any) {
this.onChange = fn;
}
registerOnTouched(fn: any) {
this.onTouched = fn;
}
}
Run Code Online (Sandbox Code Playgroud)
和模板:
<mat-checkbox [ngModel]="value" (click)="next()" [disabled]="disabled" [indeterminate]="value === false" [color]="value === false ? 'warn' : 'accent'">
<ng-content></ng-content>
</mat-checkbox>
Run Code Online (Sandbox Code Playgroud)
用法:
<app-tri-state-checkbox [(ngModel)]="done">is done</app-tri-state-checkbox>
<app-tri-state-checkbox formControlName="done">is done</app-tri-state-checkbox>
Run Code Online (Sandbox Code Playgroud)
原始答案
解决方案1: stackblitz
第一个解决方案是提供MAT_CHECKBOX_CLICK_ACTION的noop,并有所有点击事件的乐趣,但它是不是很舒服,因为你可以在同一页上多个复选框,而不是所有的人都是三态复选框.
零件:
import { MAT_CHECKBOX_CLICK_ACTION } from '@angular/material';
@Component({
selector: 'material-app',
templateUrl: 'app.component.html',
providers: [
// provide on THIS component level only
{ provide: MAT_CHECKBOX_CLICK_ACTION, useValue: 'noop' }
],
})
export class AppComponent {
tape = [null, true, false];
done = null;
doneControl = new FormControl(false);
}
Run Code Online (Sandbox Code Playgroud)
磁带(一系列切换值)值是:
null 为空复选框true 完成false 因为不会这样做然后在模板文件中使用它:
<mat-checkbox [ngModel]="done"
[indeterminate]="done === false"
(click)="done = tape[(tape.indexOf(done) + 1) % tape.length]"
[color]="done === false ? 'warn' : 'accent'">
Tri-state mat-checkbox with ngModel
</mat-checkbox>
<br>
<mat-checkbox [formControl]="doneControl"
[indeterminate]="doneControl.value === false"
(click)="doneControl.setValue(tape[(tape.indexOf(doneControl.value) + 1) % tape.length])"
[color]="doneControl.value === false ? 'warn' : 'accent'">
Tri-state mat-checkbox with formControl
</mat-checkbox>
Run Code Online (Sandbox Code Playgroud)
解决方案2: stackblitz
我遇到的另一个解决方案是更改ngModelChange处理程序以对模型的先前值做出反应.但这适用ngModel于formControl/不适用formControlName.与第一个解决方案相比有什么变化:
MAT_CHECKBOX_CLICK_ACTION被覆盖ngModelChange零件:
@Component({
selector: 'material-app',
templateUrl: 'app.component.html'
})
export class AppComponent {
tape = [null, true, false];
done = null;
doneControl = new FormControl(false);
}
Run Code Online (Sandbox Code Playgroud)
模板:
<mat-checkbox [ngModel]="done"
[indeterminate]="done === false"
(ngModelChange)="done = tape[(tape.indexOf(done) + 1) % tape.length]"
[color]="done === false ? 'warn' : 'accent'">
Tri-state mat-checkbox with ngModel
</mat-checkbox>
<br>
<mat-checkbox [formControl]="doneControl"
[indeterminate]="doneControl.value === false"
(ngModelChange)="doneControl.setValue(tape[(tape.indexOf(doneControl.value) + 1) % tape.length])"
[color]="doneControl.value === false ? 'warn' : 'accent'">
Tri-state mat-checkbox with formControl
</mat-checkbox>
Run Code Online (Sandbox Code Playgroud)
这里模型使用单向绑定设置,不确定模式严格地绑定到false值,颜色也根据值更改.
| 归档时间: |
|
| 查看次数: |
6505 次 |
| 最近记录: |