【问题标题】:How to synchronise/organise modules using requirejs and Backbone.Marionette如何使用 requirejs 和 Backbone.Marionette 同步/组织模块
【发布时间】:2024-01-08 16:03:01
【问题描述】:

我用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.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.header.show 时是否会获取app.userModel。 应该没问题吧?


// 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吗?

【问题讨论】:

标签: javascript backbone.js requirejs marionette


【解决方案1】:

1) 即使子应用需要应用,异步加载应用和子应用是否正确?

您应该能够异步加载您的app 和任何sub-apps。如果sub-apps 需要主要的app,他们应该将其列为依赖项。 RequireJS 会为你解析依赖。

你应该注意的只有循环依赖,但这不应该是你无法解决的问题。

2) subApps 是否可以加载需要该应用程序的路由器?

在您的main.js 中列出您的sub-appsrouters 听起来不错。

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

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

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

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

4) 关于这个模块我不确定app.addInitializer

我不确定例如当我执行app.header.show 时是否会获取app.userModel。应该没问题吧?

应手动启动获取数据。虽然在 Region 中显示视图确实会触发 View 被渲染,但它不会触发视图的 ModelCollection 来获取数据。

您可以做的是让您的view 监听您的ModelCollection 上的事件,并在ModelCollection 成功获取新数据后重新渲染视图。 Marionette 的CollectionView 自动将一些事件绑定到它的Collectionaddchangeremove 事件,以便在Collection 发生任何变化时自动管理它的ItemViews

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

正如我在问题 2 中所述,最好将您的路由器加载到 main.js

这样做的一个原因是,您可以决定不预先加载所有sub-apps,而是仅在实际需要时才加载它们。触发sub-app 的路由的那一刻是加载sub-app 的核心模块以及可能其中一些依赖项的最佳时机,但这当然需要sub-app 的@在加载sub-app之前激活987654363@。

【讨论】: