2013-08-21 14 views
6

私は、継承とinstanceof javascriptキーワードの使用を含むBackbone JSアプリケーションを構築しています。backgone jsモデルでinstanceofキーワードが機能しないのはなぜですか?

私は次のコードを持っている:コード内でさらに

app.Sport = Backbone.Model.extend 
({ 
    defaults: 
    { 
     id: 0, 
     title: 'Running' 
    } 
}); 

を、私は次のように入力して、新しいスポーツをインスタンス化:

var newSport = new app.Sport(); 

私は問題なく、この新しく作成されたインスタンスを操作することができます。

しかし、しかし、がありますので、私のインスタンスの種類を尋ねたときに、instanceofはキーワードは常にfalseを返します。

console.log ('is newSport a Sport instance ? ' + newSport instanceof app.Sport); 

は常にfalseを表示します。どうして ?

注:OOPの単純な形式(基本クラスの1つのインスタンスとその直後の型を求める)でも機能しないため、私の質問に継承は言及しませんでした。

私の最初の目的は、スポーツの種類(したがってinstanceofキーワードの使用)に応じて特定のアクションをトリガーすることです。それは涼しい1、または極端いずれかになります。

app.CoolSport = app.Sport.extend ({ ... }); 
app.ExtremeSport = app.Sport.extend ({ ... }); 

EDIT:私は問題を単離しました。それはinstanceofキーワードまたは宣言されたモデルにリンクされていません。むしろ、私はBackboneコレクションを作成し、それにいくつかの異なる種類のスポーツを送ります。ここにテストコードがあります:(Fiddle

var app = {}; 


app.Sport = Backbone.Model.extend 
({ 
    defaults: 
    { 
     id: 0, 
     title: 'Running' 
    } 
}); 


app.CoolSport = app.Sport.extend 
({ 
    defaults: 
    { 
     uselessAttr:'I am a Cool Sport !' 
    } 
}); 



app.SportList = Backbone.Collection.extend 
({ 
    model: app.Sport 

}); 


var coolSport1 = new app.CoolSport(); 

console.log ('is coolSport1 a Sport instance ? ' , coolSport1 instanceof app.Sport); 

console.log ('is coolSport1 a CoolSport instance ? ' , coolSport1 instanceof app.CoolSport); 

console.log ('is coolSport1 a CoolSport instance (wrong operand in console) ? ' + coolSport1 instanceof app.CoolSport); 


var sportList = new app.SportList(); 
sportList.push (coolSport1.toJSON()); 


sportList.each (function (sport) 
{ 
    if (sport instanceof app.CoolSport) 
    { 
     console.log ("sport is an instance of Cool Sport ! Yeah !" , sport instanceof app.CoolSport) ; 
    }      
    else 
    { 
     console.log ("Not a CoolSport instance.."); 
    } 
}); 

これは何ですか?私のCoolSportインスタンスはCoolSportインスタンスではありません。 Backbone SportListコレクションの初期化が問題であると思われます。

アイデア?

+0

私はフィドルあなたの問題を再現するために、私のテストは予想通り、これは動作するはず示しhttp://jsfiddle.net/nikoshr/dX7Nz/ – nikoshr

+1

を動作するようです。どのバックボーン/アンダースコアのバージョンですか? (fiddle:http://jsfiddle.net/HHS8u/) – jakee

+1

console.logを書き留めてみます( 'スポーツインスタンスのnewSportですか?'、(newSport instanceof app.Sport)); - インスタンスが取得されます。 ''はスポーツインスタンスのnewSportですか? + newSport' - それは文字列になります – Sergey

答えて

2

以下のコード:

var coolSport1 = new app.CoolSport(); 

// Of course it is 
console.log ('is coolSport1 a Sport instance ? ' , coolSport1 instanceof app.Sport); 

console.log ('is coolSport1 a CoolSport instance ? ' , coolSport1 instanceof app.CoolSport); 


var sportList = new app.SportList(); 

// Here is the tricky part : we push the JSON representation of our CoolSport instance 
sportList.push (coolSport1.toJSON()); 


// Backbone does not know anymore the subtype of our instance, as it has been JSON stringified juste before. 
sportList.each (function (sport) 
{ 
    if (sport instanceof app.CoolSport) 
    { 
     console.log ("sport is an instance of Cool Sport ! Yeah !" , sport instanceof app.CoolSport) ; 
    }      
    else 
    { 
     console.log ("Not a CoolSport instance.."); 
    } 
}); 

バックボーンのドキュメントは、この動作のためのメカニズムを提供します:

var Library = Backbone.Collection.extend({ 

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

}); 

それはリストに正しいサブタイプのインスタンスを追加するために、JSON表現を処理する方法コレクションを伝えます。だから、コードを変更せずにCoolSportを追加するには、SportListコレクションにモデル関数を追加し、 'uselessAttr'が含まれている場合は新しいCoolSportを返すだけです(私の質問のコードを参照してください)。

私は別の方法で、コレクションのadd()メソッドを通じてCoolSportインスタンスを直接渡して、そのサブタイプを保持します。

助けてくれてありがとうみんな、そして私の答えはあなたがそうあなたがcoolSport1.toJSONを(推進しているとき、「app.Sport」

としてあなたのコレクションでモデルを定義している:-)

5

してください、ないないこの:

console.log ('is newSport a Sport instance ? ' + newSport instanceof app.Sport); 

右のそれをしなさい:私はコメントし

:-)解決策を見つけた

console.log ('is newSport a Sport instance ? ' + (newSport instanceof app.Sport)); 

または

console.log ('is newSport a Sport instance ? ', newSport instanceof app.Sport); 
+2

私は決してそれを悪い方法で行うことはありません。このミスを私に指摘してくれてありがとう。私の本当の問題を述べているので、私の更新された質問を見てください。 – jeromedt

1

他人を助けることを願っています)、それは代わりにCoolSportインスタンスが、スポーツのインスタンスではありません理由ですapp.Sportモデル

を使用することによって初期化されます。

+0

私は(ちょうど下の私の答えを参照してください)あなたの前に同じ数分を発見し、そして実際にそれが正しい解決策でした。そして、もし私が自分でそれを見つけなかったら、あなたがそこにいたことをうれしく思います;-) – jeromedt

関連する問題