angular2, reusable component that can associate its ngControls with a parent ngForm

56 views
Skip to first unread message

hani

unread,
Jul 9, 2016, 3:29:42 PM7/9/16
to AngularJS
I would like to create a reusable component which has a fixed look and functionality that can be used across multiple applications. It contains `<input>` elements that require validation, so they need to be associated with the parent form where the component is defined. How do you associate the `input` in this child component with `ngForm` in its parent component?

**myComponent**

    @Component({
        selector
: 'myComponent',
       
template: `<div><input type="text" [(ngModel)]="text" /></div>` //how add ngControl and associate with parent form?
   
})
   
export class MyComponent {
        text
: string;
   
}



**app1, but there are app2 etc...**

    import {MyComponent} from './myComponent';
   
   
@Component({
        selector
: 'myComponent',
       
template: `<form #myForm="ngForm" (ngSubmit)="submited()"><myComponent></myComponent></form>`,
        directives
: [MyComponent]
   
})
   
export class MyComponent {
        submitted
() {
       
}
   
}



In each app, `myComponent` has to have its `ngControl` associated with the `ngForm` so it can be validated and accessed the same way as a regular `ngControl` which is defined directly inside of `ngForm`. Also note that adding `ngControl` without having a direct `ngForm` parent will throw an error 'no container found.'.

Gerard Lanphear

unread,
Jul 10, 2016, 1:05:40 PM7/10/16
to AngularJS
hani,
The first thing I notice is that both your components have the same selector. That would be wrong.

hani

unread,
Jul 10, 2016, 2:02:47 PM7/10/16
to AngularJS
That's a typo, thanks for the notice. The concept stands and i just inline wrote those to make a point. Any classes or forward references i could use?

Sander Elias

unread,
Jul 11, 2016, 12:40:04 AM7/11/16
to AngularJS
Hi Hani,

Did you see this documentation? and this one?

Pay attention to the *control methods off the last one! There is not yet a lot of documentation on those, but what you are asking is whole well possible!

Regards
Sander

hani

unread,
Jul 11, 2016, 9:59:33 AM7/11/16
to AngularJS
Thanks Sander,

Yes i've used those with no success. Although there are no mention of adding `ngControl` directives in child template, i've tried with/without with no success. It seems that i can't sync the inputs in child component with their parent form in case of not using `ngControl`. While using that directive will throw `no container found` which is somewhat logical as the child component doesn't have its own form.

Lesley Markesbery

unread,
Jul 11, 2016, 1:09:23 PM7/11/16
to AngularJS
Did you try having your component bind to the form control? Each application could use FormBuilder and FormControls like any other form but the actual control would be backed by your reusable input component. This does make your reusable component a very dumb (as in dumb vs. smart) control but using projection/transclusion you can still control look and feel and how errors are displayed. Using transclusion would have you break your shared component down a little further (ie. label component, error component, etc.) and that would drive the example here to be a little more complex, but conceptually something along these lines:

**myComponent**
@Component({
        selector
: 'myComponent',
        directives: [REACTIVE_FORM_DIRECTIVES ],
       
template: `<input type="text" ... [formControl]="inputFormControl" ... />`
   
})
   
export class MyComponent {
       
@Input() inputFormControl: FormControl

   
}



**app1, but there are app2 etc...**
    import {MyComponent} from './myComponent';
   
   
@Component({

        selector
: 'myApp',
       
template:`

             <form #myForm="ngForm" (ngSubmit)="submited()">
                <myComponent [inputFormControl="username"></myComponent>
             </
form>`
,
        directives
: [REACTIVE_FORM_DIRECTIVES, FormComponent, MyComponent]

Fabian Friedl

unread,
Jul 25, 2016, 12:20:52 PM7/25/16
to AngularJS
@hani Did you already solve the issue? i am facing the same problem right now... and was not able to find a solution yet.
Any help is highly appreciated. Thx 
Reply all
Reply to author
Forward
0 new messages