如何在ember-data模型中表示数组?

时间:2012-08-28 22:43:45

标签: javascript ember.js ember-data

当模型包含数组时,是否有必要使用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} })?

7 个答案:

答案 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支持

的coffeescript

答案 6 :(得分:0)

这里游戏有点晚了但是这里有一个jFiddle我发现这是一个声明一个新数组编解码器的简单实现

http://jsfiddle.net/Nook/ab2Xf/