admin管理员组文章数量:1386514
I have the following situation:
app.js: Singleton Marionette.Application() where I define a nav, a footer, and a main region. In the initializer I construct Marionette.Contoller's and attach them to the app's this.controller object for later control. I might not construct all the Controller's here, just the ones I want to Eagerly Load. Some are Lazy Loaded later. I also instantiate a Backbone.Router here, and pass in a reference to my app object:
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: this is a general use controller that handles view & model intsantiation and eventing. Each Controller owns its own Marionette.Layout, to be filled into the App.mainRegion. Each Controller binds to the layout's "show" event to fill in the layout's regions with custom views. Each Controller offers a getLayout() interface that returns the controller's associated layout.
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: the router uses the app singleton to load a Controller's layout into the App's main region:
...
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);
}
As it is, everything works fine except for reloading the same layout / controller twice. What happens is that the DOM events defined in the LoginView do not re-bind on second show. Which is easily solved by moving the LoginView initialization code into the "show" event handler for that Controller:
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);
}
Now everything works fine, but it undoes part of the reason I created Controller's to begin with: I want them to own a View and its Models, create them once, and not have to destroy & recreate them every time I switch layouts.
Am I missing something? Is this not how I should be using Layouts? Isn't the whole point of Layouts and Regions that I can switch in & out Views at will?
Obviously I wouldn't jump back to LoginController/Layout often, but what about between a HomeController/Layout, CalendarController/Layout, SummaryController/Layout, etc... in a single page application I might switch between those 'top-level' layouts rather often and I would want the view to stay cached in the background.
I have the following situation:
app.js: Singleton Marionette.Application() where I define a nav, a footer, and a main region. In the initializer I construct Marionette.Contoller's and attach them to the app's this.controller object for later control. I might not construct all the Controller's here, just the ones I want to Eagerly Load. Some are Lazy Loaded later. I also instantiate a Backbone.Router here, and pass in a reference to my app object:
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: this is a general use controller that handles view & model intsantiation and eventing. Each Controller owns its own Marionette.Layout, to be filled into the App.mainRegion. Each Controller binds to the layout's "show" event to fill in the layout's regions with custom views. Each Controller offers a getLayout() interface that returns the controller's associated layout.
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: the router uses the app singleton to load a Controller's layout into the App's main region:
...
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);
}
As it is, everything works fine except for reloading the same layout / controller twice. What happens is that the DOM events defined in the LoginView do not re-bind on second show. Which is easily solved by moving the LoginView initialization code into the "show" event handler for that Controller:
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);
}
Now everything works fine, but it undoes part of the reason I created Controller's to begin with: I want them to own a View and its Models, create them once, and not have to destroy & recreate them every time I switch layouts.
Am I missing something? Is this not how I should be using Layouts? Isn't the whole point of Layouts and Regions that I can switch in & out Views at will?
Obviously I wouldn't jump back to LoginController/Layout often, but what about between a HomeController/Layout, CalendarController/Layout, SummaryController/Layout, etc... in a single page application I might switch between those 'top-level' layouts rather often and I would want the view to stay cached in the background.
Share Improve this question asked Feb 4, 2013 at 2:17 BernardoBernardo 1,0301 gold badge12 silver badges22 bronze badges1 Answer
Reset to default 7I think your problem is that you don't maintain a single instance of the controller. The remended way to handle routing/controllers (based on Brian Mann's videos) is like this
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});
});
});
... and the controller:
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 () {
....
}
};
});
I suspect your problem is the lazy-loaded controller...
本文标签: javascriptMarionette Layout switching strategyStack Overflow
版权声明:本文标题:javascript - Marionette Layout switching strategy - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744510430a2609847.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论