6

marionette プラグインを使用してバックボーン アプリケーションをまとめようとしていますが、イニシャライザを期待どおりに動作させるのに問題があります。次のコードがあります。

var MyApp = new Backbone.Marionette.Application();

MyApp.addRegions({
    region1 : '#div1',
    region2 : '#div2'
});

MyApp.Resources = { };

MyApp.bind('initialize:before', function (options) {
    // display a modal dialog for app initialization
    options.initMessageId = noty({
        text : 'Initializing MyApp (this should only take a second or two)',
        layout : 'center',
        speed : 1,
        timeout : false,
        modal : true,
        closeOnSelfClick : false
    });
});

MyApp.addInitializer(function (options) {
    $.ajax({
        url: options.apiUrl + '/my-app-api-module',
        type: 'GET',
        contentType: 'application/json; charset=utf-8',
        success: function (results) {
            MyApp.Resources.urls = results;
            console.log(MyApp.Resources.urls); // <- THIS returns an object
        }
    });
});

MyApp.bind('initialize:after', function (options) {
    // initialization is done...close the modal dialog
    if (options.initMessageId) {
        $.noty.close(options.initMessageId);
    }

    if (Backbone.history) {
        Backbone.history.start();
    }

    console.log(MyApp.Resources.urls); // <- THIS returns 'undefined' BEFORE the console.log in the initializer above
});

上記のコードconsole.logでは、イニシャライザとinitialize:afterハンドラの 2 つの呼び出しがあることに注意してください。どちらも同じオブジェクト プロパティをログに記録します。ご覧のとおり、私が経験しているのは、ハンドラーの呼び出しconsole.logがイニシャライザーのハンドラーの呼び出しの前に呼び出されていることです。これは、イニシャライザに非同期呼び出しが含まれているためであることに気付きました...知っておく必要があるのは、アプリケーションで他のことを行う前に、イニシャライザのすべての非同期コードが完全であることを確認するにはどうすればよいかということです? これに適したパターンはありますか?これを正しく処理する方法を示すドキュメントは見つかりませんでした。initialize:aftersuccess

ありがとう。

4

3 に答える 3

7

アプリケーションで何か他のことを行う前に、初期化子のすべての非同期コードが完了していることを確認するにはどうすればよいですか?

initialize:afterイベントを使用しないでください。代わりに、success呼び出しから独自のイベントをトリガーし、そのイベントからアプリの起動コードをバインドします。

MyApp.addInitializer(function (options) {
    $.ajax({
        url: options.apiUrl + '/my-app-api-module',
        type: 'GET',
        contentType: 'application/json; charset=utf-8',
        success: function (results) {
            MyApp.Resources.urls = results;

            // trigger custom event here
            MyApp.vent.trigger("some:event:to:say:it:is:done")

        }
    });
});

// bind to your event here, instead of initialize:after
MyApp.vent.bind('some:event:to:say:it:is:done', function (options) {

    // initialization is done...close the modal dialog
    if (options.initMessageId) {
        $.noty.close(options.initMessageId);
    }

    if (Backbone.history) {
        Backbone.history.start();
    }

    console.log(MyApp.Resources.urls);
});

このようにして、非同期処理が完了した後にイベントをトリガーします。つまり、ハンドラーのコードは、最初の非同期呼び出しが返されてセットアップが完了するまで実行されません。

于 2012-07-16T16:55:20.910 に答える