diff --git a/README.md b/README.md index 89981e7a..2bc4adff 100644 --- a/README.md +++ b/README.md @@ -166,6 +166,7 @@ Be sure to call `validate()` on the `changeset` before saving or committing chan * Events + [`beforeValidation`](#beforevalidation) + [`afterValidation`](#aftervalidation) + + [`afterRollback`](#afterrollback) #### `error` @@ -743,6 +744,22 @@ changeset.validate().then(() => { **[⬆️ back to top](#api)** +#### `afterRollback` + +This event is triggered after a rollback of the changeset. +This can be used for [some advanced use cases](https://github.com/offirgolan/ember-changeset-cp-validations/issues/25#issuecomment-375855834) +where it is necessary to separately track all changes that are made to the changeset. + +```js +changeset.on('afterRollback', () => { + console.log("changeset has rolled back"); +}); +changeset.rollback(); +// console output: changeset has rolled back +``` + +**[⬆️ back to top](#api)** + ## Validation signature To use with your favorite validation library, you should create a custom `validator` action to be passed into the changeset: diff --git a/addon/index.js b/addon/index.js index e0bd9869..7e5eeba6 100644 --- a/addon/index.js +++ b/addon/index.js @@ -67,6 +67,7 @@ const OPTIONS = '_options'; const RUNNING_VALIDATIONS = '_runningValidations'; const BEFORE_VALIDATION_EVENT = 'beforeValidation'; const AFTER_VALIDATION_EVENT = 'afterValidation'; +const AFTER_ROLLBACK_EVENT = 'afterRollback'; const defaultValidatorFn = () => true; const defaultOptions = { skipValidate: false }; @@ -139,7 +140,7 @@ export type ChangesetDef = {| _validateAndSet: <T>(string, T) => (Promise<T> | Promise<ErrLike<T>> | T | ErrLike<T>), _setIsValidating: (string, boolean) => void, _validate: (string, mixed, mixed) => (ValidationResult | Promise<ValidationResult>), - trigger: (string, string) => void, + trigger: (string, string | void) => void, isValidating: (string | void) => boolean, cast: (Array<string>) => ChangesetDef, willDestroy: () => void, @@ -388,14 +389,16 @@ export function changeset( for (let key in relayCache) relayCache[key].rollback(); // Get keys before reset. - let keys = (this /*: ChangesetDef */)._rollbackKeys(); + let c /*: ChangesetDef */ = this; + let keys = c._rollbackKeys(); // Reset. set(this, RELAY_CACHE, {}); set(this, CHANGES, {}); set(this, ERRORS, {}); - (this /*: ChangesetDef */)._notifyVirtualProperties(keys) + c._notifyVirtualProperties(keys) + c.trigger(AFTER_ROLLBACK_EVENT); return this; }, diff --git a/tests/unit/changeset-test.js b/tests/unit/changeset-test.js index 00019a12..2d54e31c 100644 --- a/tests/unit/changeset-test.js +++ b/tests/unit/changeset-test.js @@ -1243,6 +1243,30 @@ test('afterValidation event is triggered with the key', function(assert) { }); }); +/** + * afterRollback + */ + +test('afterRollback event is fired after rollback', function(assert) { + let dummyChangeset; + let _validator = () => resolve(true); + let _validations = { + reservations() { + return _validator(); + } + }; + let hasFired = false; + + set(dummyModel, 'reservations', 'ABC12345'); + dummyChangeset = new Changeset(dummyModel, _validator, _validations); + dummyChangeset.on('afterRollback', () => { hasFired = true; }); + + run(() => { + dummyChangeset.rollback(); + assert.ok(hasFired, 'afterRollback should be triggered'); + }); +}); + /** * Behavior. */