0

クライアント側の既知のモデルの 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 Data シリアライザーを作成します。これは、保存する必要がある各オブジェクトのオブジェクト ID にマップされ、結果の配列を保存します。これはオブジェクトの作成には機能しますが、逆シリアル化中に ID をマップするオブジェクトがわからないため、逆シリアル化ステップは機能しません (情報はそこにはありません)。例は [1] を参照してください。
  2. ember-data をハックして、ember-data 以外のモデルとの関連付けを受け入れようとしますが、うまくいきません。

次に試みたのは、ブラウザ オブジェクトを関連付けるための仮想配列属性と、それらの ID を API に同期する配列に保存するオブザーバーを作成することでした。これは双方向で機能する必要があります。ロードされた Thingie-Object は、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'))
)
4

1 に答える 1

0

次に試みたのは、ブラウザ オブジェクトを関連付けるための仮想配列属性と、API と同期する配列に ID を保存するオブザーバーを作成することでした。これは双方向で機能する必要があります。ロードされた Thingie-Object は、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'
})

ここで留意すべきことの 1 つは、変換では id がオブジェクト配列へのインデックスであることが想定されていることです。idUI.Browser オブジェクトのプロパティは完全に無視されます。

(列挙された変換テスト)も参照してください[https://github.com/emberjs/data/blob/master/packages/ember-data/tests/integration/transform_test.js#L133-L169]

于 2013-06-18T13:06:21.947 に答える