3

Even after reading some nice tutorials and blogposts on how to structure a Backbone Marionette app, I got confused while writing my own. Here is my setup.

I have an app that can easily be structured into different sub-apps (aka Backbone modules) Click on a link in my main navigation bar starts one of these apps. That means it loads the apps starting layout into my #main div.

But these apps have different layouts in themself, so navigating inside the app overwrites regions specified in the main app layout.

e.g.

var myApp = Backbone.Marionette.Application()
...
var layout = myApp.myModule.layout = new Backbone.Marionette.Layout()
...
myApp.main.show(myApp.myModule.layout)

where layout has the following DOM tree each mapped to a region

#app_main
  .albums
  .artists

Then I do something like

layout.app_main.show(new myView())

and from now on I can not get access to layout.albums or layout.artists even after using the back button (using a Backbone.Router and History)

Should I split my module's main layout to contain only #app_main, and load the opening layout into it at a separate step? Or do you have any other ideas?

4

2 回答 2

3

了解更多关于您的目标会有所帮助,但这里有一个答案。让我知道它是否有帮助!

假设这是您的 HTML 布局:

<div id="app">
  <div id="app_nav">
    <a href="#music">Music</a>
    <a href="#books">Books</a>
  </div>
  <div id="sub_app"></div>
</div> <!-- /#app_main -->

对于我们的“音乐”子应用,我们将使用这个模板:

<script id="musicApp-template" type="template/html">
  <div class="albums"></div>
  <div class="artists"><div>
</script>

对于专辑项目视图:

<script id="album-template" type="template/html">
  <img src="<%=albumThumbSrc %>" />
  <p><%=albumTitle %></p>
</script>

对于艺术家项目视图:

<script id="artist-template" type="template/html">
  <%=firstName %> <%=lastName %>
</script>

--

对于我们的“书籍”子应用,我们将使用这个模板:

<script id="booksApp-template" type="template/html">
  <div class="books"></div>
  <div class="authors"></div>
</script>

对于图书项目视图:

<script id="book-template" type="template/html">
  <img src="<%=bookThumbSrc %>" />
  <p><%=bookTitle %></p>
</script>

对于艺术家项目视图:

<script id="author-template" type="template/html">
  <%=firstName %> <%=lastName %>
</script>

并引导应用程序:

$(document).ready({
  myApp.start();
  if(!Backbone.history.started) Backbone.history.start();
});

--

现在设置我们的 Marionette 视图。

在 myApp.js 中

var myApp = new Backbone.Marionnette.Application();

myApp.addRegions({
  subAppRegion: "#sub_app"
});

// Your data
myApp.artists = new Backbone.Collection([...]);
myApp.books = new Backbone.Collection([...]);

在 myApp.musicApp.js

myApp.module("musicApp", function(musicApp, myApp) {
  /* Setup your Views
   ================== */
  var MusicLayout = Backbone.Marionette.Layout.extend({
    template: #musicApp-template",
    regions: {
      albumsRegion: ".albums",
      artistsRegion: ".artists"
    }
  });

  var AlbumView = Backbone.Marionette.ItemView.extend({
    template: "#album-template"
  });

  var AlbumListView = Backbone.Marionette.CollectionView({
    itemView: AlbumView
  });

  var ArtistView = ...
  var ArtistListView = ...

  /* Create router for app navigation
   ==================================== */
  var Router = Backbone.Marionette.AppRouter.extend({
    appRoutes: {
      "music" : showMusicApp
    },
    controller: musicApp
  });
  new Router();

  /* Method to show the music app
   ================== */
  musicApp.showMusicApp = function() {
    // Instantiate Views
    var musicLayout = new MusicLayout();
    var albumListView = new AlbumListView({ collection: myApp.albums });
    var artistListView = new ArtistsListView({ collection: myApp.artists });

    // Show musicApp layout in subAppRegion of main app
    myApp.subAppRegion.show(musicLayout);

    // Show albums and artists in musicApp layout
    layout.albumsRegion.show(albumListView);
    layout.artistsRegion.show(artistListView);
  }
});

myApp.booksApp你可以用同样的方式设置你的模块:

myApp.module("booksApp", function(booksApp, myApp) {
  ...
  var Router = Backbone.Marionette.AppRouter.extend({
    appRoutes: {
      "books" : showBooksApp
    },
    controller: booksApp
  });
  new Router();

  booksApp.showBooksApp = function() {
    ...
    myApp.subAppRegion.show(booksLayout)
    ...
  }
  ...
});

我还没有测试所有这些代码,如果有一些问题很抱歉,我相信它可以改进。

如果您还没有阅读David Sulc 的教程,您应该看一下 - 它会让您更好地了解完整的应用程序。但我希望这能让您对如何使用布局和区域来显示不同的 subApp 视图有一个基本的了解。

于 2012-10-27T19:14:57.977 回答
0

作为我自己项目的一般规则,我总是将定义区域的元素保持为空,然后在Layout.onRender方法中动态加载它们。这在 Marionette.Async 中具有额外的好处,如果我需要在显示区域中的视图之前从服务器加载其他数据,我可以在视图的beforeRender方法中这样做。

我的规则的一个例外是在该区域的元素中显示一个动画的“正在加载...” div,一旦填充该区域就会被覆盖。

于 2012-07-14T04:45:01.350 回答