我创建了一个使用Material设计的组件(AComponent),我希望将其用作我的“反应式表单”(在AppComponent中)的formControl。
我已经在此组件(AComponent)中实现了ControlValueAccessor
。
export class AComponent implements ControlValueAccessor {
fm = new FormControl();
constructor(private ngControl: NgControl) {
ngControl.valueAccessor = this;
this.fm.valueChanges.subscribe(v => {
this.onChange(v);
})
}
onChange = (_: any) => {}
onTouched = () => {}
writeValue(obj: any) {
this.fm.setValue(obj);
}
registerOnChange(fn: any) {
this.onChange = fn;
}
registerOnTouched(fn: any) {
this.onTouched = fn;
}
}
我可以为此组件(在AppComponent中)设置Validators.required
ngOnInit() {
this.formGroup = this.fb.group({
control: ['', Validators.required],
controlOne: ['', Validators.required]
})
this.formGroup.statusChanges
.subscribe(console.log);
}
,它会影响整个表单。 (您可以在控制台上看到:当ACompnent无效时无效)。
但是问题是,在无效的情况下,我不能强制AComponent看起来无效(红色输入)。
看起来内部formControl(在AComponent中)没有从AppComponent中获得Validators.required
。
问题是:我如何以一种优雅的方式将验证器设置为AComponent?
答案 0 :(得分:1)
您需要提供NG_VALIDATORS
https://medium.com/@tarik.nzl/angular-2-custom-form-control-with-validation-json-input-2b4cf9bc2d73
答案 1 :(得分:1)
注意,当我们创建自定义表单控件时,Angular将ng-invalid ng-touched添加到我们的组件中。因此,通常我们使用.css
更改控件的外观.ng-invalid.ng-touched
{
color:red;
}
问题是我们想在自定义表单控件中更改mat-input的外观。因此,我们需要知道什么时候控制无效。
在this stackblitz中,您具有自定义的表单控件。
当您的自定义窗体控件无效时,知道密钥。为此,可以注入ngControl。使用inject避免循环依赖是必要的。所以,我们的构造函数就像
constructor(public injector: Injector) { }
ngOnInit() {
this.ngControl = this.injector.get(NgControl);
this.fm.valueChanges.subscribe(v => {
this.onChange(v);
})
}
好吧,我们知道自定义控件何时有效,被触摸,原始……
我们将定义一个.css之类的
.customError,.custom
{
display:inline-block;
}
.customError .mat-form-field-empty.mat-form-field-label {
color: red!important;
}
.customError .mat-form-field-underline {
background-color: red!important;
}
并在组件中使用ViewEncapsulation.None。 ViewEncapsulation.None使得.css处于所有应用中。这是因为我们在.mat-form-field-empty.mat-form-field-label和mat-form-field-underline之前添加了“ .customError”类。否则,我们所有的垫子组件都看起来有错误。
@Component({
selector: 'app-a',
templateUrl: './a.component.html',
styleUrls: [ './a.component.css' ],
encapsulation:ViewEncapsulation.None,
providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => AComponent),
multi: true
}]
})
此后,我们使用[ngClass]添加类
<div class="custom"
[ngClass]="{'customError':ngControl.invalid && ngControl.touched}" >
<mat-form-field
[color]="ngControl.invalid && ngControl.touched?'warn':null" >
<input matInput placeholder="Some value" [formControl]="fm" (blur)="onTouched()">
</mat-form-field>
</div>
看到我们在mat-form-field中使用属性[color]来使波纹下划线也变成红色,以及如何使用(模糊)将控件标记为触摸
答案 2 :(得分:0)
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CustomInputComponent),
multi: true
},
{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => CustomInputComponent),
multi: true
}
]
您也可以选择使用@Hostbinding设置ng-error类