web-dev-qa-db-ja.com

適切な方法でバックボーンフェッチコールバック

私のバックボーンアプリケーションにはscheduleというビューがあります。成功時とエラー時の適切な関数の呼び出しの違いについて少し混乱しています。以下にリストされている2つの可能な方法の両方を試しましたが、何をしなかったのですか?違いであり、外のビューに配置されたルーターから関数を呼び出す正しい方法は何ですか?

最初の方法:

        require([
            'app/collections/schedule',
            'app/views/schedule'
        ], function(ScheduleCollection, ScheduleView) {

           var scheduleCollection = new ScheduleCollection(),
            scheduleView = new ScheduleView({
                model: scheduleCollection
            });

            scheduleCollection.fetch({
                reset: true,                
                success: function(){
                    scheduleView.successHandler();
                },
                error: function(){
                    scheduleView.errorHandler()
                }
            });
        });

2番目の方法

        require([
            'app/collections/schedule',
            'app/views/schedule'
        ], function(ScheduleCollection, ScheduleView) {

           var scheduleCollection = new ScheduleCollection(),
            scheduleView = new ScheduleView({
                model: scheduleCollection
            });

            scheduleCollection.fetch({
                reset: true,                
                success: scheduleView.successHandler(),
                error: scheduleView.errorHandler()                  
            });
        });

scheduleView内

successHandler: function(){
   console.log('success');
}


erroHandler: function(){
   console.log('error');
}
11
ahmedsaber111

別のオプションがあります。ビューを直接参照するのではなく、関係するビューへの参照としてコレクションを提供し、関連するイベントをリッスンします。たとえば、関係するビューでコレクションのリセットをリッスンします。それがフックしたいイベントではない場合、ビューがリッスンできる成功/エラーコールバックからカスタムイベントをトリガーします。

リセット処理の例を次に示します-ScheduleViewを拡張します。

var ScheduleView = Backbone.View.extend({ 

    initialize: function () {

        this.listenTo(this.collection, 'reset', this.handleReset);
    },

    handleReset: function () {
        // do whatever you need to do here
    }
};

var scheduleCollection = new ScheduleCollection();
var scheduleView = new ScheduleView({ collection: scheduleCollection });

これは、コレクションの成功/エラーハンドラーに関連付けられたカスタムイベントの例です。

var ScheduleCollection = Backbone.Collection.extend({

    getResults: function () {

        var self = this;

        this.fetch({
            reset: true,
            success: function (collection, response, options) {
                // you can pass additional options to the event you trigger here as well
                self.trigger('successOnFetch');
            },
            error: function (collection, response, options) {
                // you can pass additional options to the event you trigger here as well
                self.trigger('errorOnFetch');
            }
        });
    }
 };

var ScheduleView = Backbone.View.extend({

    initialize: function () {

        this.listenTo(this.collection, 'successOnFetch', this.handleSuccess);
        this.listenTo(this.collection, 'errorOnFetch', this.handleError);
    },

    handleSuccess: function (options) {
        // options will be any options you passed when triggering the custom event
    },

    handleError: function (options) {
        // options will be any options you passed when triggering the custom event
    }
};

var scheduleCollection = new ScheduleCollection();
var scheduleView = new ScheduleView({ collection: scheduleCollection });
scheduleCollection.getResults();

この方法で接続することの利点は、コレクションがビューに依存していることを削除できることです。これは、コレクション(またはコレクションモデル)で発生するイベントを複数のビューでリッスンする場合に特に重要であり、バックボーンアプリケーションの疎結合アーキテクチャです。

17
kinakuta

最初の方法は正しく、2番目の方法は正しくありません。しかし、この方法は最も簡潔です:

scheduleCollection.fetch({
    reset: true,                
    success: scheduleView.successHandler,
    error: scheduleView.errorHandler
});

(ただし、OPから、関数scheduleView.successHandlerは存在しないため、問題になる可能性があります。)

5
McGarnagle

2つ目の方法が機能しない理由は、関数をすぐに実行するのではなく、参照を関数に渡す必要があるためです。

var foo = myFunction(); // foo is set to myFunction's return value
var bar = myFunction; // bar is set to a REFERENCE to myFunction

foo === bar // FALSE
bar === myFunction // TRUE

修正されたコード:

scheduleCollection.fetch({
    reset: true,                
    success: scheduleView.successHandler,
    error: scheduleView.errorHandler                  
});

さて、高度になりたい場合は、返されたXHRオブジェクトから jQuery promise API を使用する方があらゆる点で優れており、コールバックが不要になるはずです。

scheduleCollection.fetch({ reset: true })
    .then(scheduleView.successHandler, scheduleView.errorHandler);

違いは、あなたに伝えることができる約束を取り戻すということです...しかし、それは別の投稿のトピックです。 (恥知らずなプラグイン) adamterlson.com をチェックして、約束に関する私の3部構成のシリーズを確認してください...

2
Adam Terlson

関数オブジェクトを関数の戻り値ではなく、「成功」と「エラー」に割り当てる必要があります。あなたがするとき:

_function(){...}
_

関数オブジェクトを返すため、成功:function(){...}

正しいが、もし

_a = function(){...}
_

a()を実行すると、関数が実行されて戻り値が返されるため、success: a()は間違っていますが、_success: a_は正しいです。

0
2292amit