4

コレクションに を追加しているときに、 と が add イベントをリッスンしているという問題が発生してCollectionACollectionAますCollectionB。ただし、 に追加すると、両方のコレクションに対して追加イベントがトリガーされCollectionAます。 CollectionAおよびURLCollectionBを拡張して設定するだけの基本的なコレクションです。Backbone.Collection

定義を表示

ModelViewA = Backbone.View.extend({
    ...
    render : function() {
        var self       = this;
        var attributes = this.model.toJSON();
        this.$el.html(this.template(attributes));

        var collectionB     = new CollectionB();
        var collectionViewB = new CollectionViewB();
        collectionB.fetch({
            self.$el.append(collectionViewB.render().el);
        });

        return this;
    },
    ...
});

CollectionViewA = Backbone.View.extend({
    initialize : function() {
       this.collection.on('add', this.renderOne, this);
    },
    ...
    render : function() {
       this.collection.forEach(this.renderOne, this);
       return this;
    },

    renderOne : function(model) {
        console.log('Added to Collection A');

        var view = new ViewA({ model : model });
        this.$el.append(view.render().el);
        return this;
    }
});

CollectionViewB = Backbone.View.extend({
    initialize : function() {
       this.collection.on('add', this.renderOne, this);
    },
    ...
    render : function() {
       this.collection.forEach(this.renderOne, this);
       return this;
    },

    renderOne : function(model) {
        console.log('Added to Collection B');

        var view = new ViewB({ model : model });
        this.$el.append(view.render().el);
        return this;
    }
});

これらのイベントのカスケードを開始する方法は次のとおりです...

var collectionA = new CollectionA();
var modelViewA = new ModelViewA({
    model : collectionA.at('some id');
});

$('body').append(modelViewA.render().el);
$('body').empty();

var collectionViewA = new CollectionViewA({ collection: collectionA });
$('body').append(collectionViewA.render().el);
collectionViewA.add([{...}]);

このコードは、modelView を使用して初期ビューを正しく出力します。その後、適切にレンダリングされますがcollectionViewA、追加イベントをトリガーすると追加が試行されるCollectionAためCollectionB、追加イベントが呼び出されるたびにコンソールに次のように表示されます

Added to Collection B
Added to Collection A

もレンダリングしようとしますCollection Bが、テンプレートにモデルが指定されていないため、エラーがスローされます。

これがあまりにも紛らわしい場合はお知らせください。この説明をもう少し洗い流すことができます。

ありがとう!

4

1 に答える 1

1

の render メソッドで、フェッチするインスタンスをModelViewA作成するのはなぜですか?CollectionB

    var collectionB     = new CollectionB();
    var collectionViewB = new CollectionViewB();
    collectionB.fetch({
        self.$el.append(collectionViewB.render().el);
    });

それは解析さえしません。匿名の成功関数を誤って編集してしまったのではないですか? 最初に、それがあなたのコードが示しているものとはまったく違うと仮定しましょう。つまり、次のようなものになるはずです。

    collectionB.fetch({
        success: function(){
           self.$el.append(collectionViewB.render().el);
        }
    });

?

それで行きましょう。

したがって、ModelViewAがレンダリングされると、明らかに collectionB何かをフェッチしcollectionViewBてからレンダリングしようとしています。今、あなたは s をレンダリングしますModelViewAか?

CollectionViewA = Backbone.View.extend({
    initialize : function() {
       this.collection.on('add', this.renderOne, this);
    }, ...

renderOne : function(model) {
    console.log('Added to Collection A');

    var view = new ViewA({ model : model });
    this.$el.append(view.render().el);
    return this;
}

これは何ViewAですか?それも参照できModelViewAますか?

もしそうなら、私たちは何が起こっているかについて推測するかもしれません:

インスタンスは、追加するたびにCollectionViewAインスタンスをレンダリングします。ModelViewAインスタンスをレンダリングするたびにインスタンス ( ) とインスタンス( )ModelViewAが作成され、フェッチにはレンダリングする成功メソッドがあります。モデルがある場合、すべてのモデルについて、ViewB インスタンスをレンダリングしようとする前に、「コレクション B に追加されました」というコンソールに正常にログが記録されます。 B」というメッセージ。CollectionBcollectionBCollectionViewBcollectionViewBcollectionBcollectionViewBcollectionB

コンソールログが逆順になっている理由については...私はまだそれを理解しようとしています. 多分私は何かを逃した。

いずれにせよ... この状況は理想的ではありません。ただし、コードを改善するために何を言うことができるかわかりません。fetchからの呼び出しrenderは、レンダリング コードで多くのことを指定しているように思えます。そもそもそれがそこにあることをあなたが知っていたかどうかさえわかりませんfetch

于 2012-10-26T01:31:09.077 に答える