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
+90-68Lines changed: 90 additions & 68 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -24,21 +24,28 @@ ember install ember-changeset
24
24
25
25
## Updates
26
26
27
-
We have released `v3.0.0`. See the CHANGELOG [here](https://github.com/adopted-ember-addons/ember-changeset/blob/master/CHANGELOG.md). This requires Ember >= 3.13 as the use of `@tracked` will help us monitor and propagate changes to the UI layer. If your app is < 3.13 or you need to support IE11, then you can install the 2.0 series `ember install [email protected]`.
27
+
We have released `v3.0.0`. See the CHANGELOG [here](https://github.com/adopted-ember-addons/ember-changeset/blob/master/CHANGELOG.md).
28
+
This requires Ember >= 3.13 as the use of `@tracked` will help us monitor and propagate changes to the UI layer.
29
+
If your app is < 3.13 or you need to support IE11, then you can install the 2.0 series `ember install [email protected]`.
28
30
29
31
Support for IE11 was dropped with the `v3.0.0` release given our ubiquitous use of Proxy.
30
32
31
-
The base library for this addon is [validated-changeset](https://github.com/validated-changeset/validated-changeset/). As a result, this functionality is available outside of Ember as well!
33
+
The base library for this addon is [validated-changeset](https://github.com/adopted-ember-addons/validated-changeset/).
34
+
As a result, this functionality is available outside of Ember as well!
32
35
33
36
## Philosophy
34
37
35
-
The idea behind a changeset is simple: it represents a set of valid changes to be applied onto any Object (`Ember.Object`, `DS.Model`, POJOs, etc). Each change is tested against an optional validation, and if valid, the change is stored and applied when executed.
38
+
The idea behind a changeset is simple: it represents a set of valid changes to be applied onto any Object (`Ember.Object`, `DS.Model`, POJOs, etc).
39
+
Each change is tested against an optional validation, and if valid, the change is stored and applied when executed.
36
40
37
-
Assuming a Data Down, Actions Up (DDAU) approach, a changeset is more appropriate compared to implicit 2 way bindings. Other validation libraries only validate a property _after_ it is set on an Object, which means that your Object can enter an invalid state.
41
+
Assuming a Data Down, Actions Up (DDAU) approach, a changeset is more appropriate compared to implicit 2 way bindings.
42
+
Other validation libraries only validate a property _after_ it is set on an Object, which means that your Object can enter an invalid state.
38
43
39
-
`ember-changeset` only allows valid changes to be set, so your Objects will never become invalid (assuming you have 100% validation coverage). Additionally, this addon is designed to be un-opinionated about your choice of form and/or validation library, so you can easily integrate it into an existing solution.
44
+
`ember-changeset` only allows valid changes to be set, so your Objects will never become invalid (assuming you have 100% validation coverage).
45
+
Additionally, this addon is designed to be un-opinionated about your choice of form and/or validation library, so you can easily integrate it into an existing solution.
40
46
41
-
The simplest way to incorporate validations is to use [`ember-changeset-validations`](https://github.com/adopted-ember-addons/ember-changeset-validations/), a companion addon to this one. It has a simple mental model, and there are no Observers or CPs involved – just pure functions.
47
+
The simplest way to incorporate validations is to use [`ember-changeset-validations`](https://github.com/adopted-ember-addons/ember-changeset-validations/), a companion addon to this one.
48
+
It has a simple mental model, and there are no Observers or CPs involved – just pure functions.
42
49
43
50
See also the [plugins](#plugins) section for addons that extend `ember-changeset`.
changeset.save(); // sets and saves valid changes on the user
79
-
user.get('firstName'); // "Jim"
80
-
user.get('lastName'); // "Bob"
86
+
user.firstName; // "Jim"
87
+
user.lastName; // "Bob"
81
88
```
82
89
83
90
## Usage
@@ -86,29 +93,31 @@ First, create a new `Changeset` using the `changeset` helper or through JavaScri
86
93
87
94
```hbs
88
95
{{! application/template.hbs}}
89
-
{{#let (changeset model this.validate) as |changesetObj|}}
96
+
{{#let (changeset this.model this.validate) as |changesetObj|}}
90
97
<DummyForm
91
-
@changeset={{changesetObj}}
92
-
@submit={{this.submit}}
93
-
@rollback={{this.rollback}} />
98
+
@changeset={{changesetObj}}
99
+
@submit={{this.submit}}
100
+
@rollback={{this.rollback}}
101
+
/>
94
102
{{/let}}
95
103
```
96
104
97
105
```js
98
-
importComponentfrom'@ember/component';
106
+
importComponentfrom'@glimmer/component';
107
+
import { cached } from'@glimmer/tracking';
99
108
import { Changeset } from'ember-changeset';
100
109
101
110
exportdefaultFormComponentextends Component {
102
-
init(...args) {
103
-
super.init(...args)
104
-
111
+
@cached
112
+
getchangeset() {
105
113
let validator =this.validate;
106
-
this.changeset=Changeset(this.model, validator);
114
+
returnChangeset(this.model, validator);
107
115
}
108
116
}
109
117
```
110
118
111
-
The helper receives any Object (including `DS.Model`, `Ember.Object`, or even POJOs) and an optional `validator` action. If a `validator` is passed into the helper, the changeset will attempt to call that function when a value changes.
119
+
The helper receives any Object (including `DS.Model`, `Ember.Object`, or even POJOs) and an optional `validator` action.
120
+
If a `validator` is passed into the helper, the changeset will attempt to call that function when a value changes.
In the above example, when the input changes, only the changeset's internal values are updated. When the submit button is clicked, the changes are only executed if _all changes_ are valid.
164
+
In the above example, when the input changes, only the changeset's internal values are updated.
165
+
When the submit button is clicked, the changes are only executed if _all changes_ are valid.
151
166
152
167
On rollback, all changes are dropped and the underlying Object is left untouched.
`ember-changeset` overrides `set` and `get` in order to handle deeply nested setters. `mut` is simply an alias for `Ember.set(changeset, ...)`, thus we provide a `changeset-set` template helper if you are dealing with nested setters.
186
+
`ember-changeset` overrides `set` and `get` in order to handle deeply nested setters.
187
+
`mut` is simply an alias for `Ember.set(changeset, ...)`, thus we provide a `changeset-set` template helper if you are dealing with nested setters.
172
188
173
-
`changeset-get` is necessary for nested getters to easily retrieve leaf keys without error. Ember's templating layer will ask us for the first key it comes across as it traverses down the object (`user.firstName`). We keep track of the changes, but to also keep track of unchanged values and properly merge them in the changeset is difficult. If you are only accessing keys in an object that is only one level deep, you do not need this helper.
189
+
`changeset-get` is necessary for nested getters to easily retrieve leaf keys without error.
190
+
Ember's templating layer will ask us for the first key it comes across as it traverses down the object (`user.firstName`).
191
+
We keep track of the changes, but to also keep track of unchanged values and properly merge them in the changeset is difficult.
192
+
If you are only accessing keys in an object that is only one level deep, you do not need this helper.
The default behavior of `Changeset` is to automatically validate a field when it is set. Automatic validation can be disabled by passing `skipValidate` as an option when creating a changeset.
214
+
The default behavior of `Changeset` is to automatically validate a field when it is set.
215
+
Automatic validation can be disabled by passing `skipValidate` as an option when creating a changeset.
196
216
197
217
```js
198
218
let changeset =Changeset(model, validatorFn, validationMap, { skipValidate:true });
199
219
```
200
220
201
221
```hbs
202
-
{{#let (changeset model this.validate skipValidate=true) as |changesetObj|}}
222
+
{{#let (changeset this.model this.validate skipValidate=true) as |changesetObj|}}
203
223
...
204
224
{{/let}}
205
225
```
@@ -210,7 +230,7 @@ Be sure to call `validate()` on the `changeset` before saving or committing chan
Enabled in 4.1.0. Experimental and subject to changes until 5.0.
242
262
243
-
We now ship a ValidatedChangeset that is a proposed new API we would like to introduce and see if it jives with users. The goal of this new feature is to remove confusing APIs and externalize validations.
263
+
We now ship a `ValidatedChangeset` that is a proposed new API we would like to introduce and see if it jives with users.
264
+
The goal of this new feature is to remove confusing APIs and externalize validations.
244
265
245
266
- ✂️ `save`
246
267
- ✂️ `cast`
247
268
- ✂️ `merge`
248
269
-`errors` are required to be added to the Changeset manually after `validate`
249
-
-`validate` takes a callback with the sum of changes and original content to be applied to your externalized validation. In user land you will call `changeset.validate((changes) => yupSchema.validate(changes))`
270
+
-`validate` takes a callback with the sum of changes and original content to be applied to your externalized validation. In user land you will call `changeset.validate((changes) => yupSchema.validate(changes))`
250
271
251
272
```js
252
273
importComponentfrom'@glimmer/component';
@@ -363,12 +384,12 @@ Note that keys can be arbitrarily nested:
363
384
You can use this property to locate a single error:
Returns a Boolean value of the changeset's validity.
503
524
504
525
```js
505
-
changeset.get('isValid'); // true
526
+
changeset.isValid; // true
506
527
```
507
528
508
529
You can use this property in the template:
509
530
510
531
```hbs
511
-
{{#if changeset.isValid}}
532
+
{{#if this.changeset.isValid}}
512
533
<p>Good job!</p>
513
534
{{/if}}
514
535
```
@@ -520,13 +541,13 @@ You can use this property in the template:
520
541
Returns a Boolean value of the changeset's (in)validity.
521
542
522
543
```js
523
-
changeset.get('isInvalid'); // true
544
+
changeset.isInvalid; // true
524
545
```
525
546
526
547
You can use this property in the template:
527
548
528
549
```hbs
529
-
{{#if changeset.isInvalid}}
550
+
{{#if this.changeset.isInvalid}}
530
551
<p>There were one or more errors in your form</p>
531
552
{{/if}}
532
553
```
@@ -538,7 +559,7 @@ You can use this property in the template:
538
559
Returns a Boolean value of the changeset's state. A pristine changeset is one with no changes.
539
560
540
561
```js
541
-
changeset.get('isPristine'); // true
562
+
changeset.isPristine; // true
542
563
```
543
564
544
565
If changes present on the changeset are equal to the content's, this will return `true`. However, note that key/value pairs in the list of changes must all be present and equal on the content, but not necessarily vice versa:
@@ -547,13 +568,13 @@ If changes present on the changeset are equal to the content's, this will return
547
568
let user = { name:'Bobby', age:21, address: { zipCode:'10001' } };
For example, this method can be used to only allow specified changes through prior to saving. This is especially useful if you also setup a `schema` object for your model (using Ember Data), which can then be exported and used as a list of allowed keys:
910
+
For example, this method can be used to only allow specified changes through prior to saving.
911
+
This is especially useful if you also setup a `schema` object for your model (using Ember Data), which can then be exported and used as a list of allowed keys:
Your action will receive a single POJO containing the `key`, `newValue`, `oldValue`, a one way reference to `changes`, and the original object `content`.
0 commit comments