问题
I want to implement a functionality with control value accessor in Angular 5. It's like to access multiple form control in child custom component from a parent. Please let me know if I can achieve this in another way. Template driven form compulsory.
If there is any other any to generic create a custom control with two-way data binding, please let me know. It would great if answers are in Plunker or StackBlitz.
Here is mine: https://stackblitz.com/edit/angular-qzioet
Parent component :-
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() {
}
Parent html:-
<app-input name ='name'
[(ngModel)]="personal.identity.name" [form]="personalForm"
ngDefaultControl></app-input>
Child component :-
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;
};
}
Child 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>`
回答1:
What you want to do can be achieved more easily without implementing ControlValueAccessor. Instead, you can simply set the viewProviders in the child component to use the existing parent NgForm as the ControlContainer.
Then, there's no need to pass the form as an input parameter to the child component as the form controls will automatically be part of the parent's form.
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>
来源:https://stackoverflow.com/questions/52380202/multiple-form-controls-in-child-component-with-control-value-accessor-using-angu