@zensen/form-service
Version:
A reactive form service framework
196 lines (171 loc) • 4.87 kB
Markdown
# CHANGELOG
## v1.1
- Added `moveItem()` for easily moving an item to another spot in an array
- Added `swapItem()` for easily swapping two items in an array
## v2
### Selector Access to Top-Level Properties is Consistent with Sub-Level Properties
Previously, selectors accessed top-level properties were pretty direct in previous versions.
Take this model for example:
```js
const MODEL = {
email: 'john@doe.io',
name: {
first: 'John',
last: 'Doe',
},
}
```
In previous versions of `FormService`, selectors could be defined for top-level properties such as `email` like this:
```js
const SELECTORS = {
email: [isEmail],
name: [required],
}
```
Then, sub-object properties were accessed via the `children` sub-selector:
```js
const SELECTORS = {
email: [isEmail],
name: {
children: {
first: [required],
last: [required],
},
},
}
```
The `children` sub-selector was created to eliminate any potential any chance of reserved words. For example, if the `children` sub-selector didn't exist, and the data had a properties named `clipErrors` or `validators`, then `FormService` would process them as modifiers instead of as selectors. The top-level object in a `model` was treated special in the sense that it couldn't have modifiers applied to it such as `clipErrors`, `validators`, etc. This limited its use.
This has now been changed as `children` is always required to access top-level properties going forward:
```js
const SELECTORS = {
children: {
email: [isEmail],
name: [required],
},
}
```
Although this is a bit more verbose, the consistent behavior allows us to write selectors for the entire object:
```js
const SELECTORS = {
format: v => v, // format entire schema at the top-level
unformat: v => v, // format entire schema at the top-level
validators: [], // top-level validation
children: {
email: [isEmail],
name: [required],
},
}
```
This also allows the root object of the schema to be an array going forward:
```js
const MODEL = [
{
id: '1',
hp: 520,
name: 'Tidus',
},
{
id: '2',
hp: 1030,
name: 'Auron',
},
{
id: '3',
hp: 475,
name: 'Yuna',
},
]
```
```js
const SELECTORS = {
format: v => v, // format the entire array
unformat: v => v, // unformat the entire array
$: {
format: v => v, // format each array element
unformat: v => v, // unformat each array element
},
}
```
# Clearer Syntax for Declaring Selectors for Array Elements
- Also supports nested arrays
```js
const MODEL = {
emails: [
'no.one@zensen.io',
'some.one@zensen.io',
],
phones: [
{ number: '+1 (702) 555-1234', type: 'Home' },
{ number: '+1 (702) 555-5678', type: 'Work' },
{ number: '+1 (702) 699-3030', type: 'Dominos Pizza' },
],
triangles: [
[0, 1, 2],
[0, 2, 3],
],
}
const SELECTORS = {
emails: {
format: v => v, // formats model.emails
unformat: v => v,
children {
$: {
format: v => v, // formats model.emails[$]
unformat: v => v,
},
},
},
phones: {
format: v => v, // formats model.phones
unformat: v => v,
children {
$: {
format: v => v, // formats model.phones[$]
unformat: v => v,
children: {
number: {
format: v => v, // formats model.phones[$].number
unformat: v => v,
},
type: {
format: v => v, // formats model.phones[$].type
unformat: v => v,
},
},
}
},
},
triangles: {
format: v => v, // formats model.triangles
unformat: v => v,
children: {
$: {
format: v => v, // formats model.triangles[$]
unformat: v => v,
children: {
$: {
format: v => v, // formats model.triangles[$][$]
unformat: v => v,
children: {
},
},
},
},
},
},
}
```
- Renamed `genItem()` to `createItem()`
- Renamed `buildModel()` to `build()`
- Changed `createItem()` to return data in the model-form as `FormService` will convert it to state
- Remove `clipErrors` as the existence of `validators` will clip them going forward
- `validators` can be applied to a selector as long as none of their ancestor selectors apply `validators`
- Added `validateRaw` to unformat value
- Added `validateManually`
- Added params to the signature of `createItem()`: `createItem(path, index, model, service)`
- Throw an error if `validators` is defined on selectors with parent selectors that also define `validators`
- Throw an error if calling `apply()` on a key where `pristine` is type `object`
- Validation workflow with `apply()`:
- Execute if key has `validators`
- Execute `validators` on any parent keys that have them
- `unsafe` modifier to disable certain safety checks