2012-07-16 21 views
6

私は、バック・ボーン・アプリケーションをmarionetteプラグインを使ってまとめようとしていますが、イニシャライザが期待通りの動作をするのに問題があります。私は2つのconsole.log呼び出し、初期化子内の1つの、そしてinitialize:afterハンドラで1を持っている上記のコードでバックボーン・マリネット・イニシャライザで非同期コードを処理する方法

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 
}); 

注:私は、次のコードを持っています。どちらも同じオブジェクトプロパティを記録します。ご覧のとおり、initialize:afterハンドラのconsole.logコールがと呼び出されてから、の前に、イニシャライザのsuccessハンドラが呼び出されています。これは、イニシャライザが非同期呼び出しを持っていることに気付いています。私が知る必要があるのは、アプリケーション内で何かをする前に、イニシャライザ内のすべての非同期コードが完了していることを確認する方法です?これには良いパターンがありますか?私はこれを正しく処理する方法を示す文書では何も見つかりませんでした。

ありがとうございました。

答えて

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); 
}); 

あなたの非同期ものはハンドラのコードは、最初の非同期呼び出しが戻ってきたと物事が設定された後まで実行されませんを意味し、終了した後は、イベントをトリガーしているこの方法です。

+0

私はちょっと愚かではないと感じましたが、私は自分自身でそれを理解することができませんでした。ありがとうDerick。 –

+2

何もそれについて愚かではない。あなたが答えを知らないと明らかではありません:) –

+0

私はこれを考えていて、それをグーグルで愚かに感じました。あなたが投稿した構文が私の考えを明確にするのに役立った;)質問に答えるための応答と感謝のためのDerickありがとう! – jkat98

0

私は、認証のようにAsync初期化子を指定できるように、jQuery defferedsを使用してstartメソッドにオーバーライドを書きました。次に、開始メソッドはすべての遅延が解決されるまで待ってから、開始を終了します。

私は新しい同期コールバッククラスでマリオネットコールバックを置き換えるので、私はアプリで通常のメソッド呼び出しを使用できます。私の解決策を見て、それがまったく役立つかどうかを見てください。 https://github.com/AlexmReynolds/Marionette.Callbacks

0

これは、アプリケーションの残りの部分が始まる前にタスクを実行するために使用できます。 documentationを確認してください。

// Create our Application 
var app = new Mn.Application(); 

// Start history when our application is ready 
app.on('start', function() { 
    Backbone.history.start(); 
}); 

// Load some initial data, and then start our application 
loadInitialData().then(app.start); 
関連する問題