Angular4:如何在动态添加属性后重新初始化表单控件
Angular4: How to re-initialize form control after adding an attribute on the fly
所以,我制作了一个带有 "extra" 参数的表单输入组件,我可以在其中设置一些额外的输入属性,如下所示:
<form-input
type="text"
name="email"
label="Form control 1"
placeholder="Please enter your email"
[(ngModel)]="demo.name"
ngDefaultControl
[extra] = "{minlength:2}"
></form-input>
并在来源中:
@ViewChild('input') private _inputEl: ElementRef;
constructor() { }
ngOnChanges(changes: SimpleChanges){
if(changes['extra']){
if(this._inputEl && this._inputEl.nativeElement){
let attrs = Object.keys(this.extra);
attrs.forEach(attr => {
this._inputEl.nativeElement.setAttribute(attr, this.extra[attr]);
});
}
}
}
视图是这样的:
<div class="form-group">
<label for="name">{{label}}</label>
<input
#input
[name]="name"
[type]="type"
[value]="value"
class="form-control"
[(ngModel)]="ngModel"
[placeholder]="placeholder"
#name="ngModel"
>
<div [hidden]="name.valid || name.pristine" class="alert alert-danger">
Lorem text
</div>
</div>
但是,angular 验证不会针对输入框启动....但在检查器中我看到属性设置正确。
如果我将 minlength 直接放入输入元素,验证工作正常
minlength
不仅仅是添加到 HTML 元素的属性,它是将控件添加到关联的 FormControl
:
的指令
export const MIN_LENGTH_VALIDATOR: any = {
provide: NG_VALIDATORS,
useExisting: forwardRef(() => MinLengthValidator),
multi: true
};
/**
* A directive which installs the {@link MinLengthValidator} for any `formControlName`,
* `formControl`, or control with `ngModel` that also has a `minlength` attribute.
*
* @stable
*/
@Directive({
selector: '[minlength][formControlName],[minlength][formControl],[minlength][ngModel]',
providers: [MIN_LENGTH_VALIDATOR],
host: {'[attr.minlength]': 'minlength ? minlength : null'}
})
export class MinLengthValidator implements Validator,
OnChanges {
private _validator: ValidatorFn;
private _onChange: () => void;
@Input() minlength: string;
ngOnChanges(changes: SimpleChanges): void {
if ('minlength' in changes) {
this._createValidator();
if (this._onChange) this._onChange();
}
}
validate(c: AbstractControl): ValidationErrors|null {
return this.minlength == null ? null : this._validator(c);
}
registerOnValidatorChange(fn: () => void): void { this._onChange = fn; }
private _createValidator(): void {
this._validator = Validators.minLength(parseInt(this.minlength, 10));
}
}
遗憾的是,您不能对元素即时应用指令。
我担心要走的路是实现您自己的验证指令,该指令将处理您传递的对象。您可以以提供的代码为基础来执行此操作,这听起来不是一个巨大的挑战。
所以,我制作了一个带有 "extra" 参数的表单输入组件,我可以在其中设置一些额外的输入属性,如下所示:
<form-input
type="text"
name="email"
label="Form control 1"
placeholder="Please enter your email"
[(ngModel)]="demo.name"
ngDefaultControl
[extra] = "{minlength:2}"
></form-input>
并在来源中:
@ViewChild('input') private _inputEl: ElementRef;
constructor() { }
ngOnChanges(changes: SimpleChanges){
if(changes['extra']){
if(this._inputEl && this._inputEl.nativeElement){
let attrs = Object.keys(this.extra);
attrs.forEach(attr => {
this._inputEl.nativeElement.setAttribute(attr, this.extra[attr]);
});
}
}
}
视图是这样的:
<div class="form-group">
<label for="name">{{label}}</label>
<input
#input
[name]="name"
[type]="type"
[value]="value"
class="form-control"
[(ngModel)]="ngModel"
[placeholder]="placeholder"
#name="ngModel"
>
<div [hidden]="name.valid || name.pristine" class="alert alert-danger">
Lorem text
</div>
</div>
但是,angular 验证不会针对输入框启动....但在检查器中我看到属性设置正确。
如果我将 minlength 直接放入输入元素,验证工作正常
minlength
不仅仅是添加到 HTML 元素的属性,它是将控件添加到关联的 FormControl
:
export const MIN_LENGTH_VALIDATOR: any = { provide: NG_VALIDATORS, useExisting: forwardRef(() => MinLengthValidator), multi: true }; /** * A directive which installs the {@link MinLengthValidator} for any `formControlName`, * `formControl`, or control with `ngModel` that also has a `minlength` attribute. * * @stable */ @Directive({ selector: '[minlength][formControlName],[minlength][formControl],[minlength][ngModel]', providers: [MIN_LENGTH_VALIDATOR], host: {'[attr.minlength]': 'minlength ? minlength : null'} }) export class MinLengthValidator implements Validator, OnChanges { private _validator: ValidatorFn; private _onChange: () => void; @Input() minlength: string; ngOnChanges(changes: SimpleChanges): void { if ('minlength' in changes) { this._createValidator(); if (this._onChange) this._onChange(); } } validate(c: AbstractControl): ValidationErrors|null { return this.minlength == null ? null : this._validator(c); } registerOnValidatorChange(fn: () => void): void { this._onChange = fn; } private _createValidator(): void { this._validator = Validators.minLength(parseInt(this.minlength, 10)); } }
遗憾的是,您不能对元素即时应用指令。
我担心要走的路是实现您自己的验证指令,该指令将处理您传递的对象。您可以以提供的代码为基础来执行此操作,这听起来不是一个巨大的挑战。