Angular5自定义表单控件转化为formControl
Angular5 Custom Form Control Into formControl
我有这个
HTML
<div [formGroup]="frmStepTwo" fxLayout="column">
<sfc-account-selector formControlName="account">
</sfc-account-selector>
</div>
TS(查看)
this.frmStepTwo = this._formBuilder.group({
procedure: ["", Validators.required],
account: ["", Validators.required]
});
sfc-账户-selector.html
<div class="sfc-account-selector" [formGroup]="ctrlGroup">
<mat-radio-group
fxLayout="column"
(change)="inputChange($event)"
formControlName="account">
<mat-radio-button [value]="account" *ngFor="let account of accounts">
<div>
<img class="sfc-as-option-icon" [src]="imgBase + account.iconPath"/>
<div class="sfc-as-label">
<span class="sfc-as-name">{{account.serviceName}}</span>
<span class="sfc-as-desc">{{account.serviceDescription}}</span>
</div>
</div>
</mat-radio-button>
</mat-radio-group>
<small *ngIf="required">REQUIRED</small>
</div>
sfc-account-selector 是自定义表单控件。
我面临的问题是,如果我在 <sfc-account-selector>
上使用 必需属性 ,则 getter 和 setter 将触发。
如果我将我的控件包装在另一个表单控件中,则不会触发要求。
Is there a way to update the "required" when wrapping in a required formControl?
有点棘手。但是我通过这样做让它工作了。
自定义-comp.component.ts
const isParentControlRequired = function (control: FormControl) {
if (control.validator !== null) {
const validator = control.validator({}as AbstractControl);
return validator && validator.required;
}
return false;
};
export class someComponent {
....
@Input()
get required() {
return this._required;
}
set required(req) {
this._required = coerceBooleanProperty(req);
this._updateValidators();
//Emit stateChange to update value in mat-groupCtrl-field
this.stateChanges.next();
}
@Input()
get disabled() {
return this._disabled;
}
set disabled(dis) {
this._disabled = coerceBooleanProperty(dis);
this._disabled ? this.parts.disable() : this.parts.enable();
this._updateValidators();
//Emit stateChange to update value in mat-groupCtrl-field
this.stateChanges.next();
}
@Input() formControlName: string;
private _containerControl: FormControl;
constructor(private _elRef: ElementRef,
private _formBuilder: FormBuilder,
private _focusMonitor: FocusMonitor,
@Optional() @Host() @SkipSelf()
private controlContainer: ControlContainer) {
this.parts = _formBuilder.group({
"pwd": ["", this._baseValidators],
"pwdRepeat": ["", this._baseValidators],
},
{validator: valuesMatchValidation(["pwd", "pwdRepeat"])}
);
_focusMonitor.monitor(_elRef.nativeElement, true)
.subscribe(origin => {
this.focused = !!origin;
this.stateChanges.next();
});
}
ngOnInit(): void {
if (!!this.formControlName && this.controlContainer) {
this._containerControl = <FormControl>this.controlContainer.control.get(this.formControlName);
this.required = isParentControlRequired(this._containerControl);
}
ngDoCheck(): void {
if (!!this._containerControl) {
let parentCtrlDisabled = this._containerControl.disabled;
if (this.disabled !== parentCtrlDisabled) {
this.disabled = parentCtrlDisabled;
}
let parentCtrlRequired = isParentControlRequired(this._containerControl) && !parentCtrlDisabled;
if (this.required !== parentCtrlRequired) {
this.required = parentCtrlRequired;
}
}
}
我有这个
HTML
<div [formGroup]="frmStepTwo" fxLayout="column">
<sfc-account-selector formControlName="account">
</sfc-account-selector>
</div>
TS(查看)
this.frmStepTwo = this._formBuilder.group({
procedure: ["", Validators.required],
account: ["", Validators.required]
});
sfc-账户-selector.html
<div class="sfc-account-selector" [formGroup]="ctrlGroup">
<mat-radio-group
fxLayout="column"
(change)="inputChange($event)"
formControlName="account">
<mat-radio-button [value]="account" *ngFor="let account of accounts">
<div>
<img class="sfc-as-option-icon" [src]="imgBase + account.iconPath"/>
<div class="sfc-as-label">
<span class="sfc-as-name">{{account.serviceName}}</span>
<span class="sfc-as-desc">{{account.serviceDescription}}</span>
</div>
</div>
</mat-radio-button>
</mat-radio-group>
<small *ngIf="required">REQUIRED</small>
</div>
sfc-account-selector 是自定义表单控件。
我面临的问题是,如果我在 <sfc-account-selector>
上使用 必需属性 ,则 getter 和 setter 将触发。
如果我将我的控件包装在另一个表单控件中,则不会触发要求。
Is there a way to update the "required" when wrapping in a required formControl?
有点棘手。但是我通过这样做让它工作了。
自定义-comp.component.ts
const isParentControlRequired = function (control: FormControl) {
if (control.validator !== null) {
const validator = control.validator({}as AbstractControl);
return validator && validator.required;
}
return false;
};
export class someComponent {
....
@Input()
get required() {
return this._required;
}
set required(req) {
this._required = coerceBooleanProperty(req);
this._updateValidators();
//Emit stateChange to update value in mat-groupCtrl-field
this.stateChanges.next();
}
@Input()
get disabled() {
return this._disabled;
}
set disabled(dis) {
this._disabled = coerceBooleanProperty(dis);
this._disabled ? this.parts.disable() : this.parts.enable();
this._updateValidators();
//Emit stateChange to update value in mat-groupCtrl-field
this.stateChanges.next();
}
@Input() formControlName: string;
private _containerControl: FormControl;
constructor(private _elRef: ElementRef,
private _formBuilder: FormBuilder,
private _focusMonitor: FocusMonitor,
@Optional() @Host() @SkipSelf()
private controlContainer: ControlContainer) {
this.parts = _formBuilder.group({
"pwd": ["", this._baseValidators],
"pwdRepeat": ["", this._baseValidators],
},
{validator: valuesMatchValidation(["pwd", "pwdRepeat"])}
);
_focusMonitor.monitor(_elRef.nativeElement, true)
.subscribe(origin => {
this.focused = !!origin;
this.stateChanges.next();
});
}
ngOnInit(): void {
if (!!this.formControlName && this.controlContainer) {
this._containerControl = <FormControl>this.controlContainer.control.get(this.formControlName);
this.required = isParentControlRequired(this._containerControl);
}
ngDoCheck(): void {
if (!!this._containerControl) {
let parentCtrlDisabled = this._containerControl.disabled;
if (this.disabled !== parentCtrlDisabled) {
this.disabled = parentCtrlDisabled;
}
let parentCtrlRequired = isParentControlRequired(this._containerControl) && !parentCtrlDisabled;
if (this.required !== parentCtrlRequired) {
this.required = parentCtrlRequired;
}
}
}