Ember.js 如何对自定义转换的数据执行回滚
我在一个模型中使用自定义转换,如下所示:Ember.js 如何对自定义转换的数据执行回滚,ember.js,ember-data,Ember.js,Ember Data,我在一个模型中使用自定义转换,如下所示: App.Question = DS.Model.extend({ questionName: DS.attr('string'), parentQuestionId: DS.attr('number'), position: DS.attr('number'), questionLayoutId: DS.attr('number'), questionLayoutName:
App.Question = DS.Model.extend({
questionName: DS.attr('string'),
parentQuestionId: DS.attr('number'),
position: DS.attr('number'),
questionLayoutId: DS.attr('number'),
questionLayoutName: DS.attr('string'),
attributes: DS.attr('raw'),
childQuestions: DS.hasMany('question', {async: true})
});
我的转换定义为:
App.RawTransform = DS.Transform.extend({
deserialize: function (serialized) {
var obbj = Ember.Object.create();
for (var key in serialized) {
obbj.set(key, serialized[key]);
}
return obbj;
},
serialize: function (deserialized) {
return JSON.stringify(deserialized);
}
});
使用此设置,回滚不适用于转换的属性。以下是演示该问题的jsBin链接:
因此,如果您更改输入字段并单击rollback,则只会回滚名称。是否有任何解决方法可以实现对转换数据的回滚
谢谢,
Dee除非在查找/保存时,否则不会应用转换 问题是ED不知道如何跟踪记录中的pojo,因此它不会显示为脏属性,除非您更改了整个pojo,而不仅仅是pojo上的属性
你可以考虑把它变成某种关系,或者非POJO数据类型
希望这会节省一些时间,对于那些试图实现相同的人,我可以通过写下面的泛型转换来回滚: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);
}
});
AS.RawTransform=DS.Transform.extend({
/**
*递归读取json对象/数组,并将其分别转换为Ember.object和Ember.ArrayProxy
*
*@param{Object}Javascript对象
*@返回{Object}成员对象或ArrayProxy
*/
反序列化:函数(序列化){
如果(!(序列化)){
序列化={};
}
var recursiveDeserializer=函数(对象、数据){
如果(!(对象)){
if(Object.prototype.toString.call(data)='[Object Array]'){
object=Ember.ArrayProxy.createWithMixin(Ember.SortableMixin,{content:Ember.A()});
}else if(Object.prototype.toString.call(data)='[Object Object]'){
object=Ember.object.create();
}
}否则{
//在回滚时使用
if(Object.prototype.toString.call(data)='[Object Array]'){
var all=object.toArray();
all.forEach(功能(项目){
对象。移除对象(项);
});
}
}
if(Object.prototype.toString.call(data)='[Object Object]'){
for(变量输入数据){
set(_key,recursiveDeserializer(null,data[_key]);
}
}else if(Object.prototype.toString.call(data)='[Object Array]'){
对于(变量i=0,len=data.length;i
这里唯一的缺点是我不能只执行model.rollback,我必须对每个“原始”数据类型执行回滚。例如:model.get('transformeddata').rollback()
但我认为这至少是一个开始。如果能在这里添加观察员来检查,那就太好了
数据是否脏。能否详细说明“某种关系或非pojo数据类型”的含义?你的意思是我应该为属性本身定义一个模型,这有点困难,因为数据结构不是固定的,可以有不同的属性。如果它是动态的,那么关系就没有帮助了,你可能需要手动备份和还原它。您可以将pojo视为一种关系,只有当关系发生变化时,记录才会变脏,而当关系中的属性发生变化时记录才会变脏。您可以创建一个具有名称和值的
属性模型,您的问题模型可以有一个hasMany('attribute')
是的,很遗憾,就像我前面提到的,我无法为属性创建模型,因为我们不确定服务器会为属性抛出什么,它没有遵循特定的结构。我在这里添加了关于这个问题的详细问答:正是我需要的!我确实需要改变一件事,因为这段代码已经有5年的历史了。从Ember 1.13开始,ArrayProxy不再包含createWithMixins函数。我只是使用了create,并放弃了Mixin参数。