次のような状況があります。
app.js:シングルトン Marionette.Application() で、ナビゲーション、フッター、メイン リージョンを定義します。初期化子で Marionette.Contoller を構築し、後で制御できるようにアプリの this.controller オブジェクトにアタッチします。ここですべてのコントローラーを作成するわけではなく、Eagerly Load したいものだけを作成します。一部は後で遅延ロードされます。また、ここで 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:これは、ビューとモデルのインスタンス化とイベント処理を処理する汎用コントローラーです。各コントローラは、App.mainRegion に入力される独自の Marionette.Layout を所有しています。各コントローラーは、レイアウトの「表示」イベントにバインドして、レイアウトの領域をカスタム ビューで埋めます。各コントローラーは、コントローラーに関連付けられたレイアウトを返す 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);
}
そのままで、同じレイアウト/コントローラーを2回リロードすることを除いて、すべて正常に機能します。何が起こるかというと、LoginView で定義された DOM イベントが 2 回目の表示で再バインドされないということです。これは、LoginView 初期化コードをそのコントローラーの「表示」イベント ハンドラーに移動することで簡単に解決できます。
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);
}
これですべてが正常に機能しますが、最初にコントローラーを作成した理由の一部が元に戻ります。ビューとそのモデルを所有し、一度作成して、レイアウトを切り替えるたびにそれらを破棄して再作成する必要がないようにしたいのです。
何か不足していますか?これは、レイアウトを使用する方法ではありませんか? ビューを自由に切り替えることができるのは、レイアウトとリージョンの全体的なポイントではありませんか?
明らかに、LoginController/Layout に頻繁に戻ることはありませんが、HomeController/Layout、CalendarController/Layout、SummaryController/Layout などの間ではどうでしょうか... 単一ページ アプリケーションでは、これらの「トップレベル」レイアウトを切り替える可能性があります。かなり頻繁に、ビューをバックグラウンドでキャッシュしたままにしたいと思います。