I have a series of forms (each managed by 1 component).
There is a pattern of inputs in these forms (e.g. many of them require to allow input of an address) that I have to refactor into re-usable components as they are used in multiple forms and I don't want to duplicate neither their logic nor their templates.
Each re-usable component would have to
- have its logic
- have its template containing input tags and no
<form>
tag - have its client validation constraints
- possibly receive initial values from its parent
- be able to return the value of its fields to the parent as an object (e.g.
address: {street: "...", "city": "...", ...}
) - make the parent form invalid if its validation constraints are not satisfied
- make the parent form "touched" once its values have been changed by the user
From this tutorial for Angular2, I understand how to achieve objectives 1, 2 and 4.
The solution in the tutorial allows to achieve also the other objectives, but it does so by doing everything from the parent (see app.component.ts#initAddress
).
How can I achieve 3, 5, 6 and 7, while declaring controls and their constraints within the child?
You shouldn't use such implementation. It much more clean to use ControlValueAccessor.
ControlValueAccessor is an interface that allows to angular form module (classic or reactive) to write value or state and register callback to retrieve changes and event.
But you also need to provide a NG_VALUE_ACCESSOR
I wrote this quick and dirty example for an address component:
Then in a form use it like any other form element:
You could add more logic into the component. Here is a working example. Please keep in mind it's a quick example and should be rework for cleaner code.
https://stackblitz.com/edit/angular-4dgxqh
If you want to provide everything in the child component you can try something like this.
Usage:
Please note that I'm using the
ReactiveFormsModule
.Live demo
Also make sure to check out Angular Forms - Kara Erickson. The presentation shows you how to create a reusable address component with implementations for both, template driven and reactive forms.