如何使用requirejs和Backbone.Marionette同步/组织模块

时间:2012-06-22 15:56:42

标签: javascript backbone.js requirejs marionette

我以这种方式组织了我的网络应用程序的文件结构,该文件结构使用RequireJsBackbone.Marionette

|- main.js
|- app.js
|- /subapp1
    |- subapp1.js
    |- subapp1.router.js
|- /subapp2
    |- subapp2.js
    |- subapp2.router.js
|- /colections
|- /views

要加载我使用requireJs的模块。
这是我的代码,我提出了一些问题。


// main.js
define([
    'app',
    'subapp1/subapp1.router',
    'subapp2/subapp2.router'
], function (app) {
    "use strict";
    app.start();
});

问题:
1)即使子应用程序需要应用程序,也可以异步加载应用程序和子应用程序吗? 2)对于subApps是否正确加载需要app的路由器?


// app.js
/*global define*/
define([
    'backbone',
    'marionette',
    'models/user'
], function (Backbone, Marionette, UserModel) {
    "use strict";

    var App = new Marionette.Application();

    App.addRegions({
        header: '#header',
        sidebar: '#sidebar',
        mainColumn: '#main-column',
        rightColumn: '#right-column'
    });

    App.on("initialize:before", function () {
        this.userModel = new UserModel();
        this.userModel.fetch();
    });

    App.on("initialize:after", function () {
        Backbone.history.start();
    });

    return App;
});

问题:
3)由于subApps可能需要一些models,我决定将其加载到app.js。这样对吗?


// subapp1/subapp1.js
/*global define*/
define([
    'app',
    'subapp1/views/sidebarView',
    'subapp1/views/headerView'
], function (app, SidebarView, HeaderView) {
    "use strict";

    app.addInitializer(function(){
        app.header.show(new HeaderView({userModel: app.userModel}));
        app.sidebar.show(new SidebarView({userModel: app.userModel}));
    });

});

问题:
4)关于这个模块我不确定app.addInitializer 例如,我不确定在执行app.userModel时是否会提取app.header.show。 它可以吗?


// subapp1/subapp1.router.js
/*global define*/
define([
    'marionette',
    'tasks/app'
], function (Marionette, app) {
    "use strict";
    var Router = Marionette.AppRouter.extend({

        appRoutes: {
            'tasks': 'tasks',
            'tasks/:id': 'taskDetail',
            '*defaults': 'tasks'
        }

    });

    return new Router({
        controller: app
    });
});

问题:
5)可以从main.js subapp1/subapp1.router而不是subapp1/subapp1加载吗?

1 个答案:

答案 0 :(得分:1)

1)即使子应用程序需要app,也可以异步加载应用程序和子应用程序吗?

您应该可以异步加载app和任何sub-apps。如果sub-apps需要主app,则应将其列为依赖项。 RequireJS将为您解决依赖关系。

只有你应该注意的是循环依赖,但这不应该是你无法修复的任何东西。

2)对于subApps来说,加载需要app的路由器是对的吗?

在您的routers声音中列出sub-apps的{​​{1}}对我来说是正确的。

3)由于main.js可能需要一些subApps,我决定将其加载到models。这样对吗?

模块应列出它用作其依赖项的任何和所有其他模块。因此,如果app.jsapp.js都需要subapp1/subapp1.js,则他们应列出models/user.js作为其依赖项之一。

这样,如果您以不再需要models/user.js的方式更改任何模块,则可以从该特定模块中删除依赖项,而不会有丢失其他模块中的依赖项的风险。

除了作为管理依赖项的最佳方式之外,在将来查看代码时,对其他开发人员甚至是自己也很好。

4)关于这个模块我不确定models/user.js

我不确定例如,当我执行app.addInitializer时是否会提取app.userModel。它可以吗?

应手动启动提取数据。虽然在app.header.show中显示视图会触发Region呈现,但它不会触发视图的ViewModel来获取数据。

您可以做的是让Collection听取viewModel上的事件,并在Collection或{{Model后重新呈现视图1}}已成功获取新数据。 Marionette的Collection会自动将某些事件绑定到其中的CollectionViewaddchange个事件remove,以便自动管理Collection ItemViews {1}}以任何方式改变。

5)可以从Collection main.js而不是subapp1/subapp1.router加载吗?

正如我在问题2中所述,最好在subapp1/subapp1中加载路由器。

执行此操作的一个原因是,您可以决定不在前面加载所有main.js,而是仅在实际需要时加载它们。这样的sub-apps路由被触发的那一刻和加载sub-app的核心模块以及可能的某些依赖项的时间一样好,但那当然需要{{ 1}} sub-app在加载sub-app之前被激活。