我有一个反应形式。设置类似于以下内容:
myForm: FormGroup;
this.myForm= new FormGroup({
name: new FormControl("", [Validators.required, Validators.maxLength(15), Validators.pattern('...')]),
...
});
我在我的表单上使用它,如下所示:
<input
type="text"
formControlName="name"
/>
<div *ngIf="name.errors?.required">
Name is required
</div>
<div *ngIf="name.errors?.maxlength">
Name must be {{ name.errors.maxlength.requiredLength }} characters
</div>
<div *ngIf="name.errors?.pattern">
Name has invalid characters.
</div>
这只是我表格的精简版。我有多个输入,我必须为每个输入创建错误div。
因此,为了解决这个问题,我尝试创建一个组件。该组件与上面的代码非常相似:
<input
type="text"
[formControlName]="formControlName"
/>
<div *ngIf="name.errors?.required">
Name is required
</div>
etc...
TS 文件:
@Component({
selector: 'app-text',
templateUrl: './text.component.html'
})
export class TextComponent {
@Input() formControlName: FormControl;
}
所以在我的表单上,我想按如下方式使用此组件:
<app-text [formControlName]="name"></app-text>
但是我无法让它与 formControlName 属性一起使用。
这可能吗?
谢谢
我快到了。
我已经创建了这个 StackBlitz,所以显示我的进度:
演示
现在只是在为错误以及如何访问formControl以检查这些错误而苦苦挣扎
如果您想访问formControl
,最好的方法是NgControl
为 DI
推理:
-
NgModel
-
FormControlDirective
-
FormControlName
都是NgControl
的子类,所以如果你这样做,你会给自己带来很多帮助,这样,如果你改变主意使用formControl到NgControl等......你将已经通过使用NgControl
涵盖了这些基础
所以通过示例,它看起来像
import { Component, OnInit, Self } from '@angular/core';
import { NgControl } from '@angular/forms';
@Component({
selector: 'app-text',
templateUrl: './text-box.component.html',
styleUrls: ['./text-box.component.css']
})
export class TextBoxComponent implements OnInit {
constructor(@Self() private ngControl: NgControl) { }
ngOnInit() {
console.log(this.ngControl);
}
}
目录
<app-text[formControl]="control"></app-text>
我们使用@Self的原因是,组件不会进一步查找注入器树以查找ngControl
,而只会查找其元素。所以你可以嵌套等...
这对指令也非常有益,但到目前为止,我希望这有所帮助!
你需要将表单控件传递给输入元素,
<input
[value]="val"
type="text"
(input)="val=$event.target.value;onChange($event.target.value)"
(blur)="onTouched()"
[formControl]="control"
>
<span *ngIf="control && !control.valid && control.touched">
<span class="error" *ngIf="control.errors['required']"> The field should not be empty</span>
<span class="error" *ngIf="control.errors['email']"> The field should be an email
</span>
</span>
获取自定义组件中的控件作为输入,并基于此显示错误。
import { Component, OnInit, forwardRef, Input, OnChanges } from '@angular/core';
import { FormControl, ControlValueAccessor, NG_VALUE_ACCESSOR, NG_VALIDATORS } from '@angular/forms';
@Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.css'],
providers: [
{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TestComponent), multi: true }
]
})
export class TestComponent implements ControlValueAccessor, OnChanges {
constructor() { }
propagateChange:any = () => {};
@Input() control: FormControl;
@Input('messageValue') _messageValue = 'whateves';
get messageValue() {
return this._messageValue;
}
set messageValue(val) {
console.log('set messageValue', val)
this._messageValue = val;
this.propagateChange(val);
}
hi(event) {
console.log('hi');
console.log(event)
this.messageValue = event;
}
ngOnInit() {
}
ngOnChanges(changes) {
console.log('changes', changes);
this.propagateChange(this.messageValue);
}
writeValue(value) {
console.log('writeValue', value);
if (value) {
this.messageValue = value;
}
}
registerOnChange(fn) {
console.log('onChange')
this.propagateChange = fn;
}
registerOnTouched() {}
}