I want to create a Angular generic composite component which is composed of bunch of input fields which could be used inside multiple components across application.
For Example: Consider a USER DETAIL component which has following Fields,
I want to include this USER DETAIL component in multiple components as below:

From Conventional wisdom I can say, that I just include <app-userdetails> in multiple components.
But how Do I Handle the submitted FormGroupData?
I mean how do I get the data from UserDetail when its included in another component like CreateEmployee?
I am not sure if I explained the above scenario properly, please point me to any web-examples or existing questions about this.
So, to your child components you can pass form and add/remove controls to him.
Parent component template
<form (ngSubmit)="onSubmit(form)" #form="ngForm">
<a-comp [prop1]="name" [form]=form></a-comp>
<button type="submit">Submit</button>
</form>
Some child component:
// a comp
@Component({
selector: 'a-comp',
template: `
<input [(ngModel)]="prop1" name="name2" #myControl="ngModel"/>
`
})
export class AComponent {
@Input() form: NgForm;
@Input() prop1 = 'Angular 5';
@ViewChild('myControl') myControl: NgModel;
ngOnInit() {
//console.log(this.form, this.myControl);
this.form.addControl(this.myControl);
}
}
CODE EXAMPLE
Passing @Input to childs isn't necessary. But child components need to know about form.
2. Easiest way. By using power of DI
Child-component. In your case UserDetails:
@Component({
selector: 'a-comp',
viewProviders: [{ provide: ControlContainer, useExisting: NgForm }],
template: `
<input [(ngModel)]="prop1" name="prop1"/>
<input [(ngModel)]="prop2" name="prop2"/>
`
})
export class AComponent {
prop1 = 'Hello';
prop2 = 'World';
ngOnInit() { }
}
As you can see in @Component decorators we set viewProviders. So when requiring ControlContainer we say to useExisting: NgForm. By Angular DI system it will go up to find first parent NgForm.
ViewProviders = Defines the set of injectable objects that are visible to its view DOM children.
...
You maybe can ask: By
DImechanism it should search provider up to root, but why it doesn't go up in hirearchy and find parentNgForm?
Constuctor of ngModel:
constructor(@Optional() @Host() parent: ControlContainer,
@Optional() @Self() @Inject(NG_VALIDATORS) validators: Array<Validator|ValidatorFn>,
@Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) asyncValidators: Array<AsyncValidator|AsyncValidatorFn>,
@Optional() @Self() @Inject(NG_VALUE_ACCESSOR)
valueAccessors: ControlValueAccessor[]) {
...
Pay attention to @Optional() @Host() parent: ControlContainer. It's @Optional and @Host().
@Host - Specifies that an injector should retrieve a dependency from any injector until reaching the host element of the current component.
So, here @Host() decorators restrics the ngModel to search only up to host component where ngModel is allocated.
NgModel constructor
By this approach no need create @Input binding in child components to get parent NgForm and add NgModels controls manually.
StackBlitz EXAMPLE
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With