【问题标题】:Marionette Layout switching strategy木偶布局切换策略
【发布时间】:2013-02-04 02:17:41
【问题描述】:

我有以下情况:

app.js: Singleton Marionette.Application() 我在其中定义了导航、页脚和主区域。在初始化程序中,我构造 Marionette.Contoller 并将它们附加到应用程序的 this.controller 对象以供以后控制。我可能不会在这里构建所有控制器,只是我想急切加载的那些。有些是稍后延迟加载的。我还在这里实例化了一个 Backbone.Router,并传入了对我的应用对象的引用:

var theApp = new TP.Application();

theApp.addRegions(
{
    navRegion: "#navigation",
    mainRegion: "#main",
    footerRegoin: "#footer"
});

theApp.addInitializer(function()
{
    // Set up controllers container and eagerly load all the required Controllers.
    this.controllers = {};

    this.controllers.navigationController = new NavigationController({ app: this });
    this.controllers.loginController = new LoginController({ app: this });
    this.controllers.calendarController = new CalendarController({ app: this });

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

**Controller.js:这是一个通用的控制器,用于处理视图和模型实例化和事件。每个 Controller 拥有自己的 Marionette.Layout,将填充到 App.mainRegion 中。每个控制器都绑定到布局的“显示”事件以使用自定义视图填充布局的区域。每个控制器都提供了一个 getLayout() 接口,该接口返回控制器的关联布局。

Marionette.Controller.extend(
{
    getLayout: function() { return this.layout; },
    initialize: function()
    {
        this.views.myView = new MyView();
        ...
        this.layout.on("show", this.show, this);
        ...
    },
    show: function()
    {
        this.layout.myViewRegion.show(myView);
    }
});

router.js:路由器使用应用单例将控制器的布局加载到应用的主区域:

...
routes:
{
    "home": "home",
    "login": "login",
    "calendar": "calendar",
    "": "calendar"  
},
home: function ()
{
    var lazyloadedController = new LazyLoadController();
    this.theApp.mainRegion.show(lazyLoadController.getLayout());
},
login: function (origin)
{
    this.theApp.mainRegion.show(this.theApp.controllers.loginController.layout);
}

事实上,除了重新加载相同的布局/控制器两次之外,一切正常。发生的情况是 LoginView 中定义的 DOM 事件不会在第二次显示时重新绑定。这很容易通过将 LoginView 初始化代码移动到该控制器的“show”事件处理程序中来解决:

LoginController = Marionette.Controller.extend(
{
    ...
    show: function()
    {
        if (this.views.loginView)
            delete this.views.loginView.close();

        this.views.loginView = new LoginView({ model: this.theApp.session });
        this.views.loginView.on("login:success", function()
        {
        });

        this.layout.mainRegion.show(this.views.loginView);
    }

现在一切正常,但它消除了我创建控制器的部分原因:我希望他们拥有一个视图及其模型,创建一次,而不必在每次切换布局时销毁和重新创建它们.

我错过了什么吗?这不是我应该如何使用布局吗? Layouts 和 Regions 的重点不就是我可以随意切换 Views 吗?

显然我不会经常跳回 LoginController/Layout,但是在 HomeController/Layout、CalendarController/Layout、SummaryController/Layout 等之间呢? level'布局相当频繁,我希望视图保持在后台缓存。

【问题讨论】:

    标签: javascript backbone.js marionette


    【解决方案1】:

    我认为您的问题是您没有维护控制器的单个实例。处理路由/控制器的推荐方式(基于Brian Mann's videos)是这样的

    App.module('Routes', function (Routes, App, Backbone, Marionette, $, _) {
    
        // straight out of the book...
        var Router = Marionette.AppRouter.extend({
            appRoutes: {
                "home": "home",
                "login": "login",
                "calendar": "calendar"
            }
        });
    
        var API = {
            home: function () {
                App.Controller.go_home();
            },
            login: function () {
                App.Controller.go_login();
            },
            calendar: function () {
                App.Controller.go_calendar();
            }
        };
    
        App.addInitializer(function (options) {
            var router = new Router({controller: API});
        });
    });
    

    ...和控制器:

    App.module("Controller", function (Controller, App, Backbone, Marionette, $, _) {
        App.Controller = {
            go_home: function () {
                var layout = new App.Views.Main();
                layout.on('show', function () {
                    // attach views to subregions here...
                    var news = new App.Views.News();
                    layout.newsRegion.show(news);
                });
    
                App.mainRegion.show(layout);
            },
    
            go_login: function () {
                ....
            },
    
            go_calendar: function () {
                ....
            }
        };
    });
    

    怀疑你的问题是延迟加载控制器...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-20
      相关资源
      最近更新 更多