commutazione ho la seguente situazione:Marionette layout strategia
app.js: Singleton Marionette.Application() dove definisco un navigatore, un piè, ed una regione principale. Nell'inizializzatore costruisco Marionette.Contoller e li allego sull'oggetto this.controller dell'app per un controllo successivo. Potrei non costruire tutti i Controller qui, solo quelli che desidero caricare. Alcuni sono Lazy Loaded più tardi. Ho anche un'istanza di un Backbone.Router qui, e passare un riferimento al mio oggetto app:
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: questo è un controller uso generale che gestisce vista & intsantiation modello e la gestione degli eventi. Ogni Controller possiede il proprio Marionette.Layout, da inserire nell'App.mainRegion. Ogni controller si collega all'evento "mostra" del layout per riempire le regioni del layout con visualizzazioni personalizzate. Ogni controller offre un'interfaccia getLayout() che restituisce il layout associato del controller.
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: il router utilizza il singleton applicazione per caricare il layout di un controller nella zona principale della App:
...
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);
}
Così com'è, tutto funziona bene, tranne per ricaricare lo stesso layout/controller due volte. Quello che succede è che gli eventi DOM definiti in LoginView non si re-legano sul secondo show. Che è facilmente risolto spostando il codice di inizializzazione LoginView nel gestore di eventi "show" per il 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);
}
Ora tutto funziona bene, ma annulla parte del motivo che ho creato di cominciare con il controller: li voglio per possedere una vista e i suoi modelli, crearli una volta e non dover distruggere & ricrearli ogni volta che cambio layout.
Mi manca qualcosa? Non è così che dovrei usare Layouts? Non è l'intero punto di Layouts e Regioni che posso passare a Viste & a piacere?
Ovviamente non vorrei tornare indietro a LoginController/Layout spesso, ma che dire tra un HomeController/Layout, CalendarController/Layout, SummaryController/Layout, ecc ... in un'applicazione a singola pagina potrei passare da quelli in alto -levelo di layout piuttosto spesso e vorrei che la vista restasse nascosta in background.