Mar*_*tin 9 typescript angular-material angular-components angular angular5
我正在尝试通过实现 MatFormFieldControl、ControlValueAccessor 和 Validator 接口来创建自定义表单控件。
但是,当我提供NG_VALUE_ACCESSOR或NG_VALIDATORS...
@Component({
selector: 'fe-phone-number-input',
templateUrl: './phone-number-input.component.html',
styleUrls: ['./phone-number-input.component.scss'],
providers: [
{
provide: MatFormFieldControl,
useExisting: forwardRef(() => PhoneNumberInputComponent)
},
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => PhoneNumberInputComponent),
multi: true,
},
{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => PhoneNumberInputComponent),
multi: true
}
]
})
export class PhoneNumberInputComponent implements MatFormFieldControl<string>,
ControlValueAccessor, Validator, OnDestroy {
...
}
Run Code Online (Sandbox Code Playgroud)
创建循环依赖:
未捕获的错误:模板解析错误:无法实例化循环依赖!控件
这有效:
@Component({
selector: 'fe-phone-number-input',
templateUrl: './phone-number-input.component.html',
styleUrls: ['./phone-number-input.component.scss'],
providers: [
{
provide: MatFormFieldControl,
useExisting: forwardRef(() => PhoneNumberInputComponent)
}
]
})
export class PhoneNumberInputComponent implements MatFormFieldControl<string>,
ControlValueAccessor, Validator, OnDestroy {
...
constructor(@Optional() @Self() public ngControl: NgControl) {
if (this.ngControl) {
this.ngControl.valueAccessor = this;
}
}
}
Run Code Online (Sandbox Code Playgroud)
但我仍然无法弄清楚如何进行验证工作。提供NG_VALIDATORS会产生循环依赖。如果不提供它,validate方法就不会被调用。
我正在使用@angular/material 5.0.4。
为了摆脱循环依赖,我Validator从组件中删除了接口,而是直接提供验证器函数。
export function phoneNumberValidator(control: AbstractControl) {
...
}
@Component({
selector: 'fe-phone-number-input',
templateUrl: './phone-number-input.component.html',
styleUrls: ['./phone-number-input.component.scss'],
providers: [
{
provide: MatFormFieldControl,
useExisting: forwardRef(() => PhoneNumberInputComponent)
},
{
provide: NG_VALIDATORS,
useValue: phoneNumberValidator,
multi: true
}
]
})
export class PhoneNumberInputComponent implements MatFormFieldControl<string>,
ControlValueAccessor, OnDestroy {
...
constructor(@Optional() @Self() public ngControl: NgControl) {
if (this.ngControl) {
this.ngControl.valueAccessor = this;
}
}
}
Run Code Online (Sandbox Code Playgroud)