2012-07-16 4 views
6

마리오네트 플러그인을 사용하여 백본 응용 프로그램을 결합하려고하는데 예상 한대로 작동하도록 초기화 프로그램을 만드는 데 문제가 있습니다. 나는 두 console.log 전화, 이니셜 하나, 그리고 initialize:after 핸들러에서 하나가 그 위의 코드에서백본 마리오네트 이니셜 라이저에서 비동기 코드를 처리하는 방법

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

글쎄 이제는 서면으로 그 답을 보았을 때, 나는 조금 어리 석다는 느낌이 들었다. 데릭 감사합니다. –

+2

아무 것도 그것에 대해 어리 석다. 당신이 대답을 모르는 경우 그것은 분명하지 않다 :) –

+0

나는 이것을 생각하고 그것을 검색하는 어리석은 느낌. 하지만 당신이 게시 구문은 내 생각을 명확하게 도왔습니다;) 답변 Derick 감사와 질문에 대한 질문 OP! – jkat98

0

jQuery 정의를 사용하여 start 메소드에 대한 대체를 작성하여 인증과 같은 Async 초기화 프로그램을 지정할 수 있습니다. 그런 다음 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);