You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+10-67
Original file line number
Diff line number
Diff line change
@@ -6,8 +6,6 @@ Utility library to improve the robustness of your Angular forms.
6
6
7
7
Whether you have simple and tiny forms or huge and complex ones, `ngx-sub-form` will help you build a solid base for them.
8
8
9
-
- 🗜️ Tiny bundle
10
-
_(currently ~30kb as we support both the old api and the new one but soon to be ~15kb!)_
11
9
- ✅ Simple API: No angular module to setup, no `ControlValueAccessor` by hand, no inheritance, no boilerplate. Only one function to create all your forms!
12
10
- 🤖 Adds type safety to your forms
13
11
- ✂️ Lets you break down huge forms into smaller ones for simplicity and reusability
The major bump from version `5.1.2` to `6.0.0` doesn't bring any changes to the public API of `ngx-sub-form`.
54
-
It's only a major bump for Angular 11 support and you should be able to upgrade without having to update any of your forms.
55
-
56
-
That said, the version `6.0.0` also brings some exciting news!
57
-
We sneaked into that release a [complete rewrite of ngx-sub-form to get rid of inheritance](https://github.com/cloudnc/ngx-sub-form/issues/171) 🎉. The best part being: **It's been done in a non breaking way to guarantee a smooth upgrade, which can be done incrementally, one form at a time, from the old API to the new one**.
58
-
59
-
The old API has been marked as deprecated and will be removed in a few months as part of a major version bump, to give you time to upgrade.
60
-
61
-
# Migration guide to the new API
62
-
63
-
If your project is not using `ngx-sub-form` yet, feel free to skip this migration guide.
64
-
On the other hand, **if your project is using `ngx-sub-form` with the inheritance API please read the following**.
65
-
66
-
High level explanation:
67
-
68
-
- On the public API, the required changes are mostly moving things around as none of the core concepts have changed
69
-
- Depending on how much forms you have, this may be a long and boring task as we don't have any schematics to make those changes automatically for you
70
-
- On the bright side, it should be a fairly easy task in terms of complexity
71
-
- You should be able to make the upgrade **incrementally** as well _(form after form if you want to instead of a big bang rewrite!)_. This is because behind the scenes the root and sub forms communicate through the `ControlValueAccessor` interface and as this one is from Angular and didn't change, it should be fine updating one form at a time
72
-
73
-
The simplest thing to understand the new syntax is probably to have a look on the [basic API usage](#basic-api-usage) example which covers most of the cases. But let's describe a step by step approach how to update your forms:
74
-
75
-
-`createForm` is the new function to create both your root and sub forms. It's very similar in terms of configuration to all the attributes and methods that you needed to implement after extending from `NgxRootFormComponent` or `NgxSubFormComponent`
76
-
- The first parameter that you should be providing in the configuration object of `createForm` is `formType` which can be either `FormType.ROOT` or `FormType.SUB`
77
-
- Then, you can provide the following ones for a sub form:
78
-
79
-
-`formControls`
80
-
-`emitNullOnDestroy`_(optional)_
81
-
-`formGroupOptions`_(optional)_
82
-
-`toFormGroup`_(optional: If you have only 1 interface, required if you passed a second type to define a remap)_
83
-
-`fromFormGroup`_(optional: If you have only 1 interface, required if you passed a second type to define a remap)_
84
-
85
-
- And for a root form you **additionally** provide the following bindings:
86
-
87
-
-`input$`
88
-
-`output$`
89
-
-`disabled$`
90
-
-`manualSave$`_(optional)_
91
-
-`handleEmissionRate`_(optional)_
92
-
93
-
Most of the attributes and methods have the same name as they had before so it shouldn't be too much of a trouble to move from a class approach with attributes and methods to a configuration object.
94
-
95
-
On the template side, assuming that you've saved the return of the `createForm` in a `form` variable:
96
-
97
-
-`formGroupControls` will now be `form.formGroup.controls`
98
-
-`formGroupValues` will now be `form.formGroup.value`
99
-
100
-
We're exposing the original `formGroup` object but it has been augmented on the type level by making it a `TypedFormGroup<FormInterface>` which provides type safety on a bunch of attributes and methods (`value`, `valueChanges`, `controls`, `setValue`, `patchValue`, `getRawValue`). See the `TypedFormGroup` interface in `projects/ngx-sub-form/src/lib/shared/ngx-sub-form-utils.ts` if you want to know more. As a result of this, we now don't need to provide `formGroupControls` nor `formGroupValues` for type safety any more.
101
-
102
-
Previously, `transformToFormGroup`_(which is now as you guessed it `toFormGroup`)_ was taking as the first parameter `obj: ControlInterface | null` and as a second one `defaultValues: Partial<FormInterface> | null`. This was pretty annoying as you needed to define a `getDefaultValues` method to provide your default values. Now you simply define your default values within the `formControls` function on each of the form controls as you'd expect. Behind the scenes, when the component is created for the first time we make a deep copy of those default values and apply them automatically if the root form or the sub form is being updated upstream with `null` or `undefined`.
103
-
104
-
If you were previously using inheritance to set some defaults globally, for example on your root forms for the `handleEmissionRate` method, you cannot do that anymore and you'll need to define those on a per component basis! So if you were extending your own class, itself inheriting from a root form or a sub form, don't forget about that. We're considering passing a token through DI to be able to set some of those settings globally. But it's not done yet and give us feedback if you think it should.
105
-
106
-
For root forms, the helper `DataInput` has been removed. It is now by default slightly more verbose to get the input data as you have to declare a `Subject` and push values into it yourself (by using either a setter on your input or the `ngOnChanges` hook). `DataInput` was originally created to reduce this boilerplate but as there are plenty of libraries available to transform an input into an observable, we let the choice to either do it manually or install a library on your side to transform the input into an observable for you.
107
-
108
-
You can also have a look into our demo app located here: `src/app`. You'll find `main` and `main-rewrite` which are exactly the same applications but `main` is using the deprecated API (the one with inheritance) while `main-rewrite` is using the new one. As those 2 applications showcase all the features of ngx-sub-form you can easily find what you're looking for and compare both if we forgot to cover anything. Just as an FYI, we've kept both apps for now which are tested by the same E2E test suite to make sure that nothing got broken on the old API during the rewrite. When we decide to remove the old API we'll of course remove the demo implementation which is using the old API.
|`13.x`|`5.2.0` (non breaking but new API available as well) |
50
+
|`14.x`|`6.0.0` (Angular 14 upgrade only) |
51
+
|`14.x`|`7.0.0` (deprecated API is now removed) |
109
52
110
53
# API
111
54
@@ -367,7 +310,7 @@ Here are the 2 interfaces:
367
310
368
311
Example of a remap could be getting a date object that you want to convert to an ISO string date before passing that value to a date picker and before broadcasting that value back to the parent, convert it back to a date. Or vice versa.
369
312
370
-
A really interesting use case is to deal with polymorphic values. If we take the example of our live demo: https://cloudnc.github.io/ngx-sub-form we've got `src/app/main-rewrite/listing/listing-form/listing-form.component.ts`. This form can receive either a `vehicle` or a `droid`. While polymorphism works great on typescript side, when it comes to templates... It's an other story! The best way is to have 2 sub components, which will handle 1 and 1 thing: Either a `vehicle`**or** a `droid`. And in the template use an `ngIf` or an `ngSwitch` to dynamically create the expected sub form.
313
+
A really interesting use case is to deal with polymorphic values. If we take the example of our live demo: https://cloudnc.github.io/ngx-sub-form we've got `src/app/main/listing/listing-form/listing-form.component.ts`. This form can receive either a `vehicle` or a `droid`. While polymorphism works great on typescript side, when it comes to templates... It's an other story! The best way is to have 2 sub components, which will handle 1 and 1 thing: Either a `vehicle`**or** a `droid`. And in the template use an `ngIf` or an `ngSwitch` to dynamically create the expected sub form.
371
314
That said, to be able to `switch` on a value, we need to know that value: A discriminator. It'll let us know what's the type of our current object really easily, without having to create a [type guard](https://www.typescriptlang.org/docs/handbook/advanced-types.html#type-guards-and-differentiating-types) for example. And a remap is a perfect candidate for this. If you want a full example please have a look to the `listing-form.component.ts`_(path shown above)_.
Where key is a key of your main form and value, its associated value.
388
331
389
-
To see a complete example please refer to `src/app/main-rewrite/listing/listing-form/vehicle-listing/crew-members/crew-members.component.ts` and its `html` part.
332
+
To see a complete example please refer to `src/app/main/listing/listing-form/vehicle-listing/crew-members/crew-members.component.ts` and its `html` part.
0 commit comments