Ember-Data模型应该保存非Ember-Data-Models的ID - 如何?

时间:2013-06-18 10:21:45

标签: ember.js ember-data

我有一个模型应该将客户端已知模型的ID保存为服务器的数组,但我很难找到实现这一目标的好方法。

以下是客户端已知的模型类,因此应与服务器同步:

App.Browser = Em.Object.extend
  name: ''
  id: 0

App.Browser.reopenClass
  all: [
    UI.Browser.create(id: 1, name: 'Firefox')
    UI.Browser.create(id: 2, name: 'Chrome')
  ]

  find: (id) ->
    if arguments.length == 0
      return @all
    else
      @all.find((item) -> item.get('id') == id)

与服务器同步的模型如下所示:

App.Thingie = DS.Model.extend
  browserIds: DS.hasMany 'UI.Browser' # <-- this does not work, of course

到目前为止我尝试过:

  1. 使用registerTransform编写自定义Ember数据序列化程序,该序列化程序映射到需要保存的每个对象的对象ID并保存生成的数组。这适用于创建对象,但反序列化步骤不起作用,因为您不知道在反序列化期间将ID映射到哪个对象(信息在那里不可用)。示例见[1]。
  2. 尝试破解ember-data以接受与非余烬数据模型的关联,但没有运气。
  3. 接下来我要尝试的是尝试创建一个用于关联浏览器对象的虚拟数组属性,以及一个将其id保存到与api同步的数组的观察者。这将必须双向工作,因为加载的Thingie-Objects在从api(而不仅仅是id)加载时应该具有相关的对象。

    但是,也许有一种更简单的方法来实现我正在做的事情?非常感谢您的帮助。

    [1] 在模型中:

    DS.attr 'recordArray', { defaultValue: [] }
    

    在适配器中:

    DS.MyAdapter.registerTransform('recordArray',
      deserialize: (serialized) ->
        console.log('this does not work', serialized)
      serialize: (deserialized) ->
        deserialized.map((item) -> item.get('id'))
    )
    

1 个答案:

答案 0 :(得分:0)

  

接下来我要尝试的是尝试创建一个用于关联浏览器对象的虚拟数组属性,以及一个将其id保存到与api同步的数组的观察者。这将必须双向工作,因为加载的Thingie-Objects在从api(而不仅仅是id)加载时应该具有相关的对象。

这种方法会起作用。假设您的适配器将browserIds序列化为整数数组,只需将browserIds定义为模型中的计算属性。类似的东西:

App.Thingie = DS.Model.extend({
  browserIds: function(key, value) {
    // getter
    if (arguments.length === 1) {
      return this.get('browsers').getEach('id');
    // setter
    } else {
      return value.map( function(id) {
        App.Browser.find(id);
      });
    }
  }.property('browsers')
})
  

但是,也许有一种更简单的方法来实现我正在做的事情?

是的我认为你在寻找的是(枚举变换)[https://github.com/emberjs/data/blob/master/packages/ember-data/lib/system/adapter.js#L575-L605 ]。这样的事情应该有效:

DS.MyAdapter.registerEnumTransform('browsers', App.Browser.all);
App.Thingie = DS.Model.extend({
  browsers: DS.hasMany 'browsers'
})

这里要记住的一件事是转换期望id成为对象数组的索引。它将完全忽略UI.Browser对象的id属性。

另见(枚举转换测试)[https://github.com/emberjs/data/blob/master/packages/ember-data/tests/integration/transform_test.js#L133-L169]