2

この質問に続いて、Backbone.Collectionをいくつかのカスタムメソッドで拡張しようとしています。ただし、コンソールとソースの間で一貫性のない動作が発生しています。

テストは次のようになります

HTML

... 
<script type="text/javascript" src="./libs/underscore.js"></script>
<script type="text/javascript" src="./libs/backbone.js"></script>
<script type="text/javascript" src="./libs/backbone-extend.js"></script>    
<script type="text/javascript" src="./qunit/qunit.js"></script>
<script type="text/javascript" src="./backbone-extend-tests.js"></script>
</body></html>

バックボーン-extend.js

Backbone.Collection.prototype.extract = function() {
    // placeholder to test binding
    return 'foo';
};

backback-extend-tests.js

test('extending backbone', function () {
    ok(typeof Backbone.Collection.extract == 'function');
    console.log(Backbone.Collection.extract); // undefined
});

足りないものはありますか?すべてのソースが読み込まれていることを確認しました

JFTR-これ...

_.extend(Backbone.Collection, {extract:function(){return'foo';});

...プロトタイプの拡張方法を使用しないだけで機能します。Backboneのドキュメントでプロトタイプの拡張が推奨されていることを考えると、一方の方法が機能し、もう一方の方法が機能しない理由はわかりません(ただし、モデルについて具体的に言及しています)。ボンネットの下をもっと詳しく見る必要があると思います...

更新: 後世のために、これをbackbone-extend.jsファイルに配置します...

 _.extend(Backbone.Collection.prototype, {
     extract : function (model) {
     var _model = model;
     this.remove(model);
     return _model;
 }
 });

...動作します

4

2 に答える 2

10

いくつかの重要な概念を混同しているため、期待する動作が見られません。これは、より基本的なjavascriptの質問であり、バックボーンに完全に関連しているわけではありません。

次のコンストラクターについて考えてみます。

var Klass = function() {};

キーワードを使用してそのコンストラクターを呼び出し、newそのコンストラクターからインスタンスを取得できます。

var klassInstance = new Klass();

ここで、そのコンストラクターから派生したすべてのインスタンスで使用可能なメソッドを追加したいとします。そのために私はprototypeオブジェクトを使用することができます。

Klass.prototype.instanceMethod = function() { alert('hi'); };

次に、次を使用してそのメソッドを呼び出すことができるはずです。

klassInstance.instanceMethod();

ただし、静的関数を追加することもできます。このコンテキストでは、この用語を大まかに使用します。コンストラクター自体に、インスタンスがなくても呼び出すことができます。

Klass.staticMethod = function() { alert('yo!'); };

このメソッドはコンストラクターから直接利用できますが、インスタンスから直接利用することはできません。

例えば:

klassInstance.staticMethod == undefined

したがって、テストの実際の問題は、メソッドをprototype–に追加していることです。これは、その「クラス」のすべてのインスタンスで使用できるメソッドですが、テストでは、「クラス」自体で直接メソッドをテストしています。これは同じことではありません。


余談ですが、Backbone.jsは、組み込み型の「サブクラス」を作成するための組み込みメカニズムを提供します。これは静的 .extend()メソッドです。これにより、基本のバックボーンクラスに独自の機能を追加する簡単な方法が提供されます。

あなたの場合、あなたは次のようなことをしたいと思うでしょう:

var MyCollection = Backbone.Collection.extend({
    extract: function() {
        // do whatever
    }
}) 

次に、次のように言うことで、新しいクラスのインスタンスを作成できます。インスタンスには.extract()メソッドがあります。

var coll = new MyCollection();
coll.extract();

TL; DR;

最終的に–元の質問に戻ります–特定のクラスのすべてのインスタンスで使用できるメソッドが必要な場合、テストは正しくありません。テストするインスタンスを新しくする必要があります。

test('extending backbone', function () {
    var col = new Backbone.Collection();
    ok(typeof col.extract == 'function');
});

または、メソッドを直接確認します。これは、オブジェクトがメソッドを取得する唯一のオブジェクトではないprototypeという点で微妙に異なります。prototype

test('extending backbone', function () {
    ok(typeof Backbone.Collection.prototype.extract == 'function');
});
于 2012-10-15T14:28:03.527 に答える
0

テストを実行する前にbackbone.js、とが完全にロードされていることを確認してください。underscore.js

于 2012-10-15T12:01:08.007 に答える