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处理程序中。两者都记录相同的对象属性。如您所见,我遇到的是处理程序中的console.log调用在初始化程序处理程序中的调用之前initialize:after被调用。我意识到这是因为初始化程序中有一个异步调用......我需要知道的是,在应用程序中执行任何其他操作之前,如何确保我的初始化程序中的所有异步代码都是完整的? 这有一个好的模式吗?我在文档中没有找到任何指示如何正确处理此问题的内容。success

谢谢。

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 回答
0

我使用 jQuery defereds 重写了 start 方法,因此您可以指定一个异步初始化器,如身份验证。start 方法然后等待直到所有延迟都被解决,然后完成启动。

我用我的新同步回调类替换了木偶回调,这样我就可以在应用程序中使用常规方法调用。看看我的解决方案,看看是否有帮助。https://github.com/AlexmReynolds/Marionette.Callbacks

于 2014-01-06T21:08:02.180 回答
0

这可用于在应用程序的其余部分开始之前完成任务。检查文档

// 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);
于 2015-07-03T18:42:52.800 回答