I use custom transformation in one of my model like this:
App.Question = DS.Model.extend({
questionName: DS.attr(\'string\'),
parentQuestion
Hopefully this will save some time for people who are trying to achieve the same, I was able to do rollback by writing following generic transformation:
AS.RawTransform = DS.Transform.extend({
/**
* Recursively read through the json object/array and convert it into Ember.Object and Ember.ArrayProxy respectively
*
* @param {Object} Javascript object
* @returns {Object} Ember Object or ArrayProxy
*/
deserialize: function (serialized) {
if (!(serialized)) {
serialized = {};
}
var recursiveDeserializer = function (object, data) {
if (!(object)) {
if (Object.prototype.toString.call(data) === '[object Array]') {
object = Ember.ArrayProxy.createWithMixins(Ember.SortableMixin, { content: Ember.A()});
} else if (Object.prototype.toString.call(data) === '[object Object]') {
object = Ember.Object.create();
}
} else {
//used when rolling back
if (Object.prototype.toString.call(data) === '[object Array]') {
var all = object.toArray();
all.forEach(function (item) {
object.removeObject(item);
});
}
}
if (Object.prototype.toString.call(data) === '[object Object]') {
for (var _key in data) {
object.set(_key, recursiveDeserializer(null, data[_key]));
}
} else if (Object.prototype.toString.call(data) === '[object Array]') {
for (var i = 0, len = data.length; i < len; i++) {
object.get('content').push(recursiveDeserializer(null, data[i]));
}
} else {
return data;
}
return object;
};
var ret = recursiveDeserializer(null, serialized);
ret.reopen({
/**
* This function reverts back changes made to the content of Ember Object/Array
* */
rollback: function () {
var self = this;
Ember.run(function () {
recursiveDeserializer(self, serialized);
});
}
});
return ret;
},
/**
* Recursively read through the Ember.Object/Ember.ArrayProxy and convert it into javascript array or object
*
* @param {Object} Ember ArrayProxy or Object
* @return {Object} Javascript object
* */
serialize: function (deserialized) {
var recursiveSerializer = function (object, data) {
if (!(object)) {
if (data instanceof Ember.ArrayProxy) {
object = [];
} else if (data instanceof Ember.Object) {
object = {};
}
}
/**
* Couldn't use instanceof command to check the type
* because for some reason at this point the data
* is seen as Object even if it is an array
* */
if (Object.prototype.toString.call(object) === '[object Object]') {
for (var _key in data) {
if (data.hasOwnProperty(_key) &&
_key.indexOf('__ember') < 0 &&
_key.indexOf('_super') < 0 &&
Ember.typeOf(data.get(_key)) !== 'function'
) {
object[_key] = recursiveSerializer(null, data[_key]);
}
}
} else if (Object.prototype.toString.call(object) === '[object Array]') {
data.forEach(function (d) {
object[object.length] = (recursiveSerializer(null, d));
});
} else {
return data;
}
return object;
};
return recursiveSerializer(null, deserialized);
}
});
The only drawback here is that I cannot just do model.rollback, I have to perform rollback on each 'raw' data type. eg: model.get('tranformedData').rollback()
But I think this is at-least a start. It would be nice to also add observers here to check if the data is dirty or not.