I use custom transformation in one of my model like this:
App.Question = DS.Model.extend({
questionName: DS.attr(\'string\'),
parentQuestion
The transformations don't get applied except on find/save.
The problem is ED doesn't know how to track your pojo living on your record, so it doesn't show up as a dirty attribute, unless you changed the entire pojo, not just an property on the pojo.
You might consider making it into some relationship, or non pojo data type
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.