2012-05-01 11 views
17

私のモデルでカスタムコンストラクタを作成するためのいくつかの例を探しています。私は構造体をモデル/データと違って属性として設定するだけです。Backbone.jsカスタムコンストラクタ?

誰かに私にこれを行う方法のいくつかの基本的な例を示すことができますか?

ありがとうございます!

+1

「parse」(http://documentcloud.github.com/backbone/#Model-parse)を使用して、必要に応じてサーバーのJSONを変換できます。おそらく、あなたがしようとしていることを明確にする必要があります。 –

答えて

39

は、Backbone.Model.extend()constructorプロパティを渡す、例えば:initializeメソッドをオーバーライドすることは正しい方法であるあなたは、組み込みのコンストラクタを呼び出したい場合は

var Klass = Backbone.Model.extend({ 

    constructor : function (attributes, options) { 

    // ... 

    } 

}); 

あなたのカスタムコンストラクタから、次のようなことができます:

var Klass = Backbone.Model.extend({ 

    constructor : function (attributes, options) { 

    Backbone.Model.apply(this, arguments); 

    } 

}); 

またはvaの名前を繰り返す必要がない場合

var Klass; 

var parent_klass = Backbone.Model.prototype; 

(function (parent_klass) { 

    Klass = parent_klass.constructor.extend({ 

    constructor : function (attributes, options) { 

     parent_klass.constructor.apply(this, arguments); 

    } 

    }); 

})(parent_klass); 

それとも道@Claude suggestsを好む場合は、すべてのサブクラス上の親クラスを含む、またはあなたがその変数変化の値を心配する必要はありません、あなたは以下のような何かを行うことができriable代わりに、親クラスのvar名のサブクラス内のサブクラス変数名を繰り返す:

var Klass = Backbone.Model.extend(

    { 

    constructor : function (attributes, options) { 

     Klass.parent_klass.constructor.apply(this, arguments); 

    } 

    }, 

    { 

    parent_klass : Backbone.Model.prototype 

    } 

); 

あなたがより多くのアドバイスをしたい場合は、あなたが達成したいかについて、より具体的にする必要があります。

組み込みのコンストラクター機能の後に実行したいことは、initialize()で行う必要があります。

_.extend(Backbone.Collection.prototype, { 
    model: Backbone.Model 
}); 

:あなたはBackbone.Collectionプロトタイプが更新Backbone.Modelコンストラクタを使用して確認する必要がありその後

Backbone.Model = (function(Model) { 
    // Define the new constructor 
    Backbone.Model = function(attributes, options) { 
    // Your constructor logic here 
    // ... 
    // Call the default constructor if you wish 
    Model.apply(this, arguments); 
    // Add some callbacks 
    this.on('event', this.myCallback, this); 
    }; 
    // Clone static properties 
    _.extend(Backbone.Model, Model);  
    // Clone prototype 
    Backbone.Model.prototype = (function(Prototype) { 
    Prototype.prototype = Model.prototype; 
    return new Prototype; 
    })(function() {}); 
    // Update constructor in prototype 
    Backbone.Model.prototype.constructor = Backbone.Model; 
    return Backbone.Model; 
})(Backbone.Model); 

+1

__super__を 'this'と組み合わせて使用​​する場合は注意してください。 'this'は常に作成されるオブジェクトを指し、無限ループにつながります。詳細は私の返信を参照してください。 – Claude

+0

@Claudeはい、それに言及してくれてありがとうございます。私は答えを更新することを意味してきました。私はこの回答を投稿してから '__super__'を使用して停止しました。 – JMM

+0

プロトタイプを使用してモデルのすべてのインスタンスのコンストラクタを作成する方法はありますか?私はBackbone.Modelのインスタンスが作成されたときにコンストラクタメソッドを変更しようとしています。私はノードのsocket.ioフレームワークでいくつかの自動バインディング作業を実行したいと思います。 BuT私が作成する各モデルにコンストラクタメソッドをアタッチする必要はありません。初期化作業のプロトタイプを追加する。唯一の問題は、アンダースコア拡張メソッドでオーバーライドしたモデルを渡す場合です。 – kr1zmo

0

initializeメソッドを探しているようです。あなたがそれを必要とするものは何でものための場合は、新しいモデルを作成するときに呼び出されます、あなたが使用することができます。

var myModel = Backbone.Model.extend({ 
    initialize: function() { 
    // do something besides setting attributes or model 
    alert('myModel is ready for action!'); 
    } 
}); 

new myModel(); 

あなたがより複雑な何かを探しているなら、あなたはバックボーンコアにconstructorメソッドをオーバーライドすることがあります。それは、しかし、はるかにトリッキーなビジネスです。あなたができるなら公開されたメソッドで動作する方がはるかに良い!

+1

私はカスタムコンストラクタを探しています。私は、送られた属性を単純にモデルに設定する必要はありません。私はコンストラクタをオーバーライドしようとしています。 – fancy

+1

もちろん、オプションハッシュを 'initialize'に渡して関数内で操作し、必要な属性をそこから設定することができます。 – rjz

+0

'constructor'は「公開」されており、どのように文書を上書きできるか説明しています。 'initialize'は別の目的を果たします。 – Madbreaks

2

あなたはこのように、自分でモデルを作成したい場合:

var YourModel = function() { 
    // your constructor here 
}; 

_.extend(YourModel.prototype, Backbone.Model.prototype, { 
    // your model method here 
}); 

は注意してください、私はあなたがBackbone.Modelコンストラクタsource codeに相談する必要があると思います。しかし、これは良い考えではないと私は思う。あなたが本当にコンストラクタをオーバーライドする場合

var YourModel = Backbone.Model.extend({ 
    initialize: function (attrs, options) { 
     Backbone.Model.prototype.initialize.apply(this, arguments); // call super constructor 

     // your constructor code here 
    } 
}); 
+0

'Backbone.Model'の初期化メソッドは空です。それを呼び出す際に何らかのポイントがあるかどうかはわかりません。 – raine

+0

@rane将来のリリースではこれが確実になるでしょうか?間違いなくsuperメソッドを呼び出すことは賢明です。 – Madbreaks

6

これは私がデフォルトBackbone.Modelコンストラクタをオーバーライドする方法です私の意見では、このアプローチの「利点」は、モデルのコンストラクタとしてBackbone.Modelを使用し続けることができるため、変更がより透明になります。

+1

+1は私のモデルを何か他のものに広げない – blockhead

7

this.constructor.__super__(またはthis.__super__)を使用する場合は、無限ループ(ChromeではMaximum call stack size exceeded)になるように注意してください。

理由はBのインスタンスへAポイントのコンストラクタで、thisBを作成するときにということである

var A = Backbone.Model.extend({constructor: function() { 
    console.log("log: A"); 
    this.constructor.__super__.constructor.apply(this, arguments); 
}}); 

var B = A.extend({constructor: function() { 
    console.log("log: B"); 
    this.constructor.__super__.constructor.apply(this, arguments); 
}}); 

new A(); 
// log: A 
// > Backbone.model.extend.constructor 
new B(); 
// log: B 
// (8192) log: A 
// > RangeError: Maximum call stack size exceeded 

(自身の責任で、それは前述上記の無限ループにつながる)、コンソールに次のように試してみてくださいしたがって、this.constructor.__super__.constructorは、Aのコンストラクタの方向を指し続けます。

あなたは「意図した行動を」したい場合は、次のいずれかの構文を使用します。__super__なし

var A = Backbone.Model.extend({constructor: function() { 
    console.log("log: A"); 
    A.__super__.constructor.apply(this, arguments); 
}}); 

var B = A.extend({constructor: function() { 
    console.log("log: B"); 
    B.__super__.constructor.apply(this, arguments); 
}}); 

new A(); 
// log: A 
// > Backbone.model.extend.constructor 
new B(); 
// log: B 
// log: A 
// > A.extend.constructor 

または直接:

var A = Backbone.Model.extend({constructor: function() { 
    console.log("log: A"); 
    Backbone.Model.apply(this, arguments); 
}}); 

var B = A.extend({constructor: function() { 
    console.log("log: B"); 
    A.apply(this, arguments); 
}}); 

new A(); 
// log: A 
// > Backbone.model.extend.constructor 
new B(); 
// log: B 
// log: A 
// > A.extend.constructor 
-1

Backbone.Modelコンストラクタをオーバーライドするときに注意すべき何か - Backbone.Model.applyを呼び出さないと、Model.cidが設定されないことがあります。

これは悪いです - 複数のモデル間でcidが設定されていないと、コレクションではコレクションの最初のモデルと重複しているとみなされ、追加されません。