MarionetteJS和"子应用程序"

Mat*_*och 4 architecture marionette

我正在开发一个具有几个不同功能区域的MarionetteJS Web应用程序.例如,一个是"仪表板",另一个是"组",第三个是"事件",每个都有自己的特定路线.

例如

  • /仪表板显示#
  • /组#列表
  • /组#显示/ 123
  • /事件#V/9876 /与会者

等等

在过去,我使用Marionette模块将主Application对象分割成可以启动和停止的部分.当正在开发的应用程序是100%单页应用程序时这很有用 - 这意味着我可以从服务器加载MVC路由(例如http://example.com/dashboard)并启动相应的Marionette组件. http://example.com/groups将启动一组不同的木偶组件

在当前状态下(在撰写本文时,2.4.2),Marionette已弃用Module组件,转而采用其他模块加载机制.在上面给出的示例中,是否仍然可以使用不同的架构方法将Marionette应用程序分段为独立触发的片段?我看到它的方式,我可以:

  1. 创建多个Marionette.Application()对象并将它们彼此独立地加载.
  2. 利用Marionette.Object()并以某种方式将Marionette.Application()对象扩展为子组件.
  3. 创建一个"主"路由器,侦听根URL(事件/,仪表板,组),然后创建"子路由器",扩展它以提供更多功能.

Jac*_*cob 5

我会使用CommonJS模块采用以下方法.这些子应用程序或模块无法启动或停止,但它们提供了良好的分离.

app.js

var Marionette = require('backbone.marionette');
var _ = require('underscore');

module.exports = Marionette.Application.extend({
    initialize: function() {
        this._modules = [];
    },

    addModule: function(name, klass ,options) {
        var module = new klass(options);

        this._modules[name] = module;
    }
});
Run Code Online (Sandbox Code Playgroud)

layout.js

var Marionette = require('backbone.marionette');

module.exports = Marionette.LayoutView.extend({
    el: '#app',

    regions: {
        header: '[data-region="header"]',
        main: '[data-region="main"]'
    }
});
Run Code Online (Sandbox Code Playgroud)

组/ index.js

var Marionette = require('backbone.marionette');

var Router = require('./router');

var Group = require('./model/group');
var GroupCollection = require('./model/group_collection');

var GroupListView = require('./list/collection_view');
var GroupDetailView = require('./detail/group_view');

module.exports = Marionette.Object.extend({
    initialize: function(options) {
        this.container = options.container;

        this.router = new Router({
            controller: this
        });

        this.groups = new GroupCollection();
    },

    groupList: function() {
        var groupListView = new GroupListView({
            collection: this.groups
        });

        this.groups.fetch();

        this.container.show(groupListView);
    },

    groupDetail: function(id) {
        var groupDetailView = new GroupDetailView({
            model: this.groups.findWhere({id: id})
        });

        this.container.show(groupDetailView);
    }
});
Run Code Online (Sandbox Code Playgroud)

组/ router.js

var Marionette = require('backbone.marionette');

module.exports = Marionette.AppRouter.extend({
    appRoutes: {
        'groups': 'groupList',
        'groups/:id': 'groupDetail'
    }
});
Run Code Online (Sandbox Code Playgroud)

main.js

var Backbone = require('backbone');

var Application = require('./app');
var MainLayout = require('./layout');

var HeaderApp = require('./header');
var GroupsApp = require('./groups');

var app = new Application();
var layout = new MainLayout();

app.addModule('header', HeaderApp, {
    container: layout.getRegion('header')
});

app.addModule('groups', GroupsApp, {
    container: layout.getRegion('main')
});

app.start();

Backbone.history.start({
    pushState: true
});
Run Code Online (Sandbox Code Playgroud)

我省略了这个例子中的模型,集合和视图,但我希望你能得到这个要点.

您的应用程序是扩展的Marionette应用程序,您可以在其中注册模块.

每个模块都在其自己的文件夹中,并带有index.js文件,该文件用作模块的入口点.在此文件中,您将构建一个Marionette对象,用作模块的控制器.

每个模块都有自己的路由器,在index.js文件中有Marionette对象作为它的控制器.

随意添加模型,集合,视图和模板.对于模块之间的通信,您可以使用Backbone.Radio.

最后,您在main.js中引导您的应用程序,主要布局和模块,并使用browserify或webpack构建它.

放弃

我自己并没有发明这种架构,但此刻我不记得原始来源.