当模型包含数组时,是否有必要使用DS.hasMany
指向DS.Model
?即使数组元素不是真正的模型(没有自己的ID或端点)?还有更好的方法吗?
我正在使用DS.hasMany
,但我的扩展DS.RESTAdapter
让我试图访问该模型的404,即使我从未在其上调用find
,{{1使用hasMany
调用。我第一次看到这个错误(显然与这个模型有关,因为没有它就会消失):
{ embedded: true }
这意味着什么以及可能导致什么?
这是堆栈跟踪:
Uncaught Error: assertion failed: Emptying a view in the inBuffer state is not allowed and should not happen under normal circumstances. Most likely there is a bug in your application. This may be due to excessive property change notifications. ember-latest.js:43
感谢您的帮助。
更新: This fiddle有效(来自docs的示例),但如果标签不是真实模型,那么如何表示这些对象(即{{3} })?
答案 0 :(得分:52)
嗯......这有点困难,但在这篇文章中混合了所有答案,我把它弄清楚了。
首先,您应该为新类型“array”创建一个转换:
DS.ArrayTransform = DS.Transform.extend({
deserialize: function(serialized) {
return (Ember.typeOf(serialized) == "array")
? serialized
: [];
},
serialize: function(deserialized) {
var type = Ember.typeOf(deserialized);
if (type == 'array') {
return deserialized
} else if (type == 'string') {
return deserialized.split(',').map(function(item) {
return jQuery.trim(item);
});
} else {
return [];
}
}
});
App.register("transform:array", DS.ArrayTransform);
现在,在您的模型中,只需将其用作另一个attr:
App.myModel = Ember.Model.extend({
name : DS.attr('string'),
cont : DS.attr('array')
}
我们完成了。 请记住,在向数组添加元素时,要使用pushObject。
在控制器中:
this.get('model.cont').pushObject('new Item');
我希望这有助于某人。
答案 1 :(得分:29)
我使用raw
转换,在ember-data revision 11中看起来像这样:
DS.RESTAdapter.registerTransform('raw', {
deserialize: function(serialized) {
return serialized;
},
serialize: function(deserialized) {
return deserialized;
}
});
然后,在模型中,我这样做:
App.MyModel = Ember.Model.extend({
anArray: DS.attr('raw')
});
可以在任何地方像常规数组一样使用anArray
。
答案 2 :(得分:20)
以下是在Ember-Data(版本10)中创建自定义数组类型的示例:
DS.JSONTransforms.array =
# If the outgoing json is already a valid javascript array
# then pass it through untouched. In all other cases, replace it
# with an empty array. This means null or undefined values
# automatically become empty arrays when serializing this type.
serialize: (jsonData)->
if Em.typeOf(jsonData) is 'array' then jsonData else []
# If the incoming data is a javascript array, pass it through.
# If it is a string, then coerce it into an array by splitting
# it on commas and trimming whitespace on each element.
# Otherwise pass back an empty array. This has the effect of
# turning all other data types (including nulls and undefined
# values) into empty arrays.
deserialize: (externalData)->
switch Em.typeOf(externalData)
when 'array' then return externalData
when 'string' then return externalData.split(',').map((item)-> jQuery.trim(item))
else return []
现在您可以在模型属性中使用自定义类型:
App.CalenderWeek = DS.Model.extend
selected_days = DS.attr('array')
现在当您使用以下内容获取记录时
App.CalendarWeek.find(1)
这两个传入的json记录都会正确地反序列化为数组:
{ selected_days: ['Monday', 'Tuesday', 'Saturday'] }
或
{ selected_days: 'Monday, Tuesday, Saturday' }
答案 3 :(得分:9)
在 Ember Data 1.0.0 Beta 中,已经有人能够“注册”他或她的自定义转换“子类”。我更愿意将其称为扩展的DS.Transform
对象。
DS.ArrayTransform = DS.Transform.extend({
deserialize: function(deserialized) {
// ...
return deserialized;
},
serialize: function(serialized) {
// ...
return serialized;
}
});
App.register('transform:array', DS.ArrayTransform);
答案 4 :(得分:4)
如果您绝对需要与服务器交换自定义数据结构,则可以丰富DS.attr.transforms
并声明新的array
编解码器,例如。
有关现有属性编解码器实现,请参阅source code。这是一个开始添加自己的好地方。
答案 5 :(得分:1)
有趣的是,这个问题的所有其他4个答案都具有几乎相同的反序列化和序列化函数,因此您可以简化为:
import Em from 'ember'
import DS from 'ember-data'
# Presumably based on these answers: http://stackoverflow.com/questions/12168570/how-to-represent-arrays-within-ember-data-models
# All we need to do is always make sure an array is returned from serialize or deserialize
toArray = (data) ->
switch Em.typeOf(data)
when 'array' then data
when 'string' then JSON.parse(data)
else []
export default DS.Transform.extend
deserialize: toArray
serialize: toArray
这是ember-cli-coffees6使用import/export
支持
答案 6 :(得分:0)
这里游戏有点晚了但是这里有一个jFiddle我发现这是一个声明一个新数组编解码器的简单实现