ember-data-change-tracker
New
- Experimental feature
- isDirty, hasDirtyRelations computed properties
- Set up in configuration as { enableIsDirty: true }
- It is experimental and a has one crippling defect, it can not track object type attributes. But if you don't have object types it works fine.
- isDirty, hasDirtyRelations computed properties
This addon aims to fill in the gaps in the change tracking / rollback that ember data does now.
-
Currently ember-data
- tracks changes for numbers/strings/date/boolean attributes
- has a
changedAttributes()
method to see what changed => [ last, current ] - has a
rollbackAttributes()
method to rollback attributes - has a
hasDirtyAttributes
computed property
-
This addon:
- tracks modifications in attributes that are object/json/custom type
- tracks replacement of belongsTo associations
- tracks replacement/changes in hasMany associations
- adds a
modelChanges()
method to DS.Model - adds a
rollback()
method to DS.Model - adds a
isDirty
computed property to DS.Model ( only if enabled in configuration ) - adds a
hasDirtyRelations
computed property to DS.Model ( only if enabled in configuration ) - Only works with
- ember-data versions 2.7+ ( if you have polymphic relationships )
- ember-data versions 2.5+ ( if you don't )
- Can be used in two modes
- auto track mode
- manual track mode ( the default )
Installation
ember install ember-data-change-tracker
Why?
Say there is a user model like this:
;
You can not currently rollback the info, json if they are modified or company, profile, projects and pets if they change.
model changes
- The method
modelChanges()
is added to model - Shows you any changes in an object attribute type
- whether modified or replacing the value
- attr() will default to 'object' type
- works with any custom type you have created
- Shows when you replace a belongsTo association
- Shows when you add to a hasMany association
- Shows when you delete from a hasMany association
- Merges ember-data
changeAttribute()
information into one unified change object - Unlike ember-data no last and current value is shown, just the boolean => true
- Though you will see [last value, current value] for the attributes that ember-data tracks
Example: ( remove from a hasMany )
user; // remove project1 user //=> {projects: true }
Rollback
- The method
rollback()
is added to model - If you're not using auto track you have to call
startTrack()
before editing - Performace wise, it's way faster than you think it should be.
- Tested on model with hundreds of items in a hasMany association.
- Though you might want to think twice when tracking one with thousands
Usage:
- make and makeList are from ember-data-factory-guy.
- they create and push models ( based on factories ) into the ember-data store
let info = foo: 1; let projects = ; let project1 = projects; let pets = ; let cat cat2 = pets; let bigCompany = ; let smallCompany = ; let user = ; // manual tracking model means you have to explicitly call => startTrack // to save the current state of things before you edit user; // edit things user; user; // it's all back to the way it was user //=> {foo: 1} user //=> profile1 user //=> bigCompany user //=> first 2 projects user //=> back to the same 4 pets
isDirty, hasDirtyRelations
- Computed properties to check if the model has changed
- Not enabled by default
- Need to set enableIsDirty ( true ) on model or global configuration
- The only attributes that can NOT be tracked with isDirty are object/array attributes
Usage:
let info = foo: 1; let pets = ; let cat cat2 = pets; let bigCompany = ; let smallCompany = ; let user = ; user; // edit things user; user; //=> true user; user; //=> false user; user; //=> true user; //=> true user; user; //=> false user; user; //=> true user; //=> true user; user; //=> false // things that don't work user; user; //=> false ( object/array attributes don't work for computed isDirty )
Configuration
-
Global configuration
- By default the global settings are:
- { trackHasMany: true, auto: false, enableIsDirty: false }
- Essentially this says, track everything in the model but only when I tell you
- Since this is manual mode you probably want to track everything since you are focused on one edit at a time, hence trackHasMany is on
- { trackHasMany: true, auto: false, enableIsDirty: false }
- The options available are:
- trackHasMany : should hasMany associations be tracked? ( true is default )
- this is just a shortcut to exclude all the hasMany relations
- auto : should tracking be turned on by default? ( false is default )
- auto tracking means when any model is saved/updated/reloaded the tracker will save the current state, allowing you to rollback anytime
- enableIsDirty : sets up computed properties on a model
hasDirtyRelations
for checking on changed relationshipsisDirty
for checking on any changes- NOTE: not working for object type attributes, since those are too difficult to observe for the purpose of computed properties
- trackHasMany : should hasMany associations be tracked? ( true is default )
- By default the global settings are:
-
Model configuration
- Takes precedence over global
- So, globally auto track could be off, but on one model you can turn it on
- The options available are:
- trackHasMany : same as global trackHasMany
- auto : same as global auto
- only : limit the attributes/associations tracked on this model to just these
- except : don't include these attributes/associations
- You can use 'only' and 'except' at the same time, but you could also clean your nose with a pipe cleaner
- Takes precedence over global
// file config/environment.js var ENV = modulePrefix: 'dummy' environment: environment rootURL: '/' locationType: 'auto' changeTracker: trackHasMany: true auto: true EmberENV: ... rest of config
- Set options on the model
// file app/models/user.js ;
Serializer extras
- Mixin is provided that will allow you to remove any attributes/associations that did not change from the serialized json
- Useful when you want to reduce the size of a json payload
- removing unchanged values can be big reduction at times
Example:
Let's say you set up the user model's serializer with keep-only-changed mixin
// file: app/serializers/user.js;; RESTSerializer;
Then when you are updating the user model
user;user; //=> '{ info: {"foo:1"} }'
Without this mixin enabled the json would look like:
name: "dude" info: "foo:1" company: "1" companyType: "company" profile: "1"
where all the attributes and association are included whether they changed or not
Extra's
- Adds a few more helpful methods to ember data model
didChange(key)
- did the value on this key change?
savedTrackerValue(key)
- this is the value that the key had after it was created/saved and before any modifications
Usage:
user; // saves all keys that are being tracked user //=> {foo: 1} original value of info user user //=> true user //=> {foo: 1} original value of info
Known Issues
- When pushing data to the store directly to create a model ( usually done when using
websockets .. but same issue if using factory guy) you need to call
model.saveTrackerChanges()
manually after creating that new model - Testing
- In unit / integration tests you have to manually initialize change-tracker if you are testing anything that requires the addon to be enabled
For example:
;;; ;