我想在Angular 5中实现带有控件值访问器的功能。这就像从父级访问子级自定义组件中的多个表单控件一样。请让我知道我是否可以通过其他方式实现这一目标。 强制使用模板驱动的表单。
如果还有其他任何通用的创建带有双向数据绑定的自定义控件,请告诉我。如果答案是Plunker或StackBlitz,那就太好了。
这是我的:https://stackblitz.com/edit/angular-qzioet
父组件:-
export class AppComponent implements OnInit {
public countryList: any = [];
public option: any =[ ];
public personal = {
identity: {
name: {firstname: null, lastname: null },
age: null,
sex: null
}
}
@ViewChild('personalForm') form: any;
constructor() {
}
父html:-
<app-input name ='name'
[(ngModel)]="personal.identity.name" [form]="personalForm"
ngDefaultControl></app-input>
子组件:-
import {Component, Input, forwardRef} from '@angular/core'
import {
FormControl,
FormGroup,
ControlValueAccessor,
NG_VALUE_ACCESSOR,
NG_VALIDATORS,
Validator
} from '@angular/forms';
@Component({
selector: 'app-input',
templateUrl: "./input-child.html",
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => Child),
multi: true
},
{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => Child),
multi: true,
}
]
})
export class Child implements ControlValueAccessor, Validator {
@Input() form: any;
@Input() name: any;
childControl = new FormGroup({ firstname: new FormControl() ,
lastname: new FormControl() });
fn: (value: any) => void;
constructor() {
console.log(this.childControl);
}
writeValue(value: any) {
if (value) {
this.childControl.setValue(value);
}
}
registerOnChange(fn: (value: any) => void) {
this.fn = fn;
}
registerOnTouched() {}
validate(c: FormControl) {
return this.childControl.errors;
};
}
子html:-
`<h1>Child</h1>
<div>
<input [formControl]="firstname" (input)="fn($event.target.value)"
required>
<input [formControl]="lastname" name="lastname"
(input)="fn($event.target.value)" required>
</div>`
答案 0 :(得分:1)
无需实现ControlValueAccessor,可以更轻松地实现您想要的操作。 相反,您只需在子组件中设置viewProviders即可将现有的父NgForm用作ControlContainer。
然后,由于表单控件将自动成为父表单的一部分,因此无需将表单作为输入参数传递给子组件。
input-child.component.ts:
@Component({
selector: 'input-child',
templateUrl: './input-child.component.html',
viewProviders: [{ provide: ControlContainer, useExisting: NgForm}]
})
export class Child {
@Input() personalName = {};
...
}
input-child.component.html:
<h1>Child</h1>
<div>
<input [(ngModel)]="personalName.firstname" name="firstname" required>
<input [(ngModel)]="personalName.lastname" name="lastname" required>
</div>
parent.component.ts:
export class AppComponent {
public countryList: any = [];
public option: any =[ ];
public personal = {
identity: {
name: {firstname: 'first-name', lastname: 'last-name' },
age: null,
sex: null
}
}
...
}
parent.component.html:
<form #personalForm="ngForm" name="personalForm">
<child-input [personalName]="personal.identity.name"></child-input>
</form>