9

私は動物のコレクションを持っています。

App.Collections.Animals extends Backbone.Collection
  model: App.Animal
  url: '/animals/' #returns json

そして、これらの動物のクラス:

App.Models.Animal extends Backbone.Model

App.Models.Monkey extends App.Models.Animal
  defaults:{type:'Monkey'}

App.Models.Cat extends App.Models.Animal
  defaults:{type:'Cat'}

App.Models.Dog extends App.Models.Animal
  defaults:{type:'Dog'}

コレクションが JSON で満たされている (レコードにtype属性が含まれている) 場合、モデルを Animal としてではなく、サブクラス化されたモデル (Monkey、Cat、Dog) としてインスタンス化する必要があります。どうすればこれを達成できますか?

4

3 に答える 3

12

バックボーンのドキュメントから:

モデルを返す関数でこのプロパティをオーバーライドすることにより、コレクションにポリモーフィック モデルを含めることもできます。

var Library = Backbone.Collection.extend({

  model: function(attrs, options) {
    if (condition) {
      return new PublicDocument(attrs, options);
    } else {
      return new PrivateDocument(attrs, options);
    }
  }

});
于 2013-04-17T01:03:21.160 に答える
6

解決策は簡単です (JS は許してください。CoffeeScript はわかりません)。

var SmartZoo = Backbone.Collection.extend({
    model: function (attrs, options) {
        // This code assumes that the object looks something like '{ type: "Cat", ... }'.
        switch (attrs.type) {
            case 'Cat':
                return new Cat(attrs, options);
            case 'Dog':
                return new Dog(attrs, options);
            default: // Unknown subclass
                return new Animal(attrs, options);
        }
    }
});

必ず:

  1. 作成するバックボーン モデルのタイプを推測できる属性をモデルに含めます。この例では、オブジェクトに「type」という属性が含まれています。その値は、それを表すバックボーン タイプの完全な名前です。コレクションに実際のモデル インスタンスを追加できるように、必ずモデルのデフォルトまたは初期化に設定してください。
  2. コレクションのモデル プロパティを関数として定義します。この関数の最初のパラメーターは、生の JS オブジェクト (それを渡した場合)、またはバックボーン モデルの属性オブジェクトになります。どちらの方法でも、このオブジェクトのプロパティとして type フィールドにアクセスできます。
  3. ロジックを実行して、型フィールドから適切なモデルを推測します。
  4. models 関数から正しいモデルのインスタンスを返します。

これは、このポリモーフィック コレクションの動作を示す JSFiddle です: http://jsfiddle.net/FiddlerOnTheTarmac/uR2Sa/

于 2014-02-13T18:12:52.630 に答える
0

バックボーン コレクションの _prepareModel をオーバーライドします。コレクション new は、定義されている場合はサブクラスを使用し、それ以外の場合はデフォルト モデルを使用します。

class App.Collections.Animals extends Backbone.Collection

 model: App.Models.Animal

 _prepareModel: (attrs, options) ->
   if attrs instanceof Backbone.Model
   attrs.collection = @
   return attrs

   options || (options = {})
   options.collection = @
   model_class = APP.Models[attrs.ntype] or this.model
   model = new model_class(attrs, options)
   if (!model._validate(attrs, options))
     false
   else
     model
于 2013-03-20T15:06:54.720 に答える