2012-07-06 12 views
16

私はマリオネットで大規模なjavascriptアプリケーションを開始しています。うバックボーンマリオネットとRequireJSモジュール

require([ "jquery", "underscore", "backbone", "marionette" ], 
function ($, _, Backbone, Marionette) { 
    $(function() { 

     App = new Marionette.Application(); 
     App.addInitializer(function(options) { 
      App.addRegions({ 
       mainArea: "#mainArea" 
      }); 
     }); 

     App.on("start", function() { 
      // done starting up, do stuff here 
     }); 

     App.start(); 
    }); 
}); 

私はビューを追加したい場合:マリオネット・アプリケーションは、アプリケーションモジュールの概念を持っており、RequireJSもモジュールにコードを破るために使用され、

現在、私は自分のアプリケーションの起動のためにこれを持っています私はファイルの中で次のようなことをしますか?

require([ "jquery", "underscore", "backbone", "marionette" ], 
function($, _, Backbone, Marionette) { 

    App.module("FirstView", function(FirstView, App, Backbone, Marionette, $, _) { 
     return Marionette.ItemView.extend({ 
      //define view stuff in here 
     }); 
    }); 

}); 

私は任意のヘルプは非常に

答えて

23

マリオネットのモジュールがRequireJS(およびその他)のモジュール形式の簡単な選択肢であることを意味している評価されて、私は実際に実行するには、このコードを取得したいかどうかはわかりません。ウィキに述べたように、私は、それらを一緒に使用してお勧めしません:私はマリオネットのモジュールは、単純なRequireJSの代替(およびその他)であることを意味している」上記で述べた観点から異なるのが好き

https://github.com/marionettejs/backbone.marionette/wiki/AMD-Modules-vs-Marionette's-Modules

+0

は理にかなっています。ありがとう!私は、私がBBCloneMailのような頭のスクリプトタグにすべてのアプリケーションファイルを貼り付けなければならない、マリオネットモジュールを使用したと仮定しているので、RequireJSを使用するつもりです。 –

+1

複数のスクリプトタグを使用することはお勧めしません。 BBCloneMailはそのようなことを行う例ではありません。 :)実際のプロジェクトでは、連結して縮小するビルドステップがあります。 r.jsはrequirejsモジュールのために行うか、Railsのアセットパイプラインやgrunt.jsや他の多くのツールのような多くのツールで行うことができます。 –

+2

ここに、RequireJSでMarionetteを使用するための更新リンクがあります。 (githubリポジトリが移動しました)https://github.com/marionettejs/backbone.marionette/wiki/Using-marionette-with-requirejs –

4

私見をモジュールフォーマット "

私は、Require.jsモジュールとMarionette.jsモジュールをC#のアセンブリと名前空間の概念で比較したいと思います。 Marionette.jsのモジュールは、機能に基づいてさまざまなビルディングブロックの定義をグループ化するのに役立ちますが、Require.jsを使用して依存関係をロード/注入することができます。

これは私の実装に役立ったDavid Sulc氏の書籍「RequireJSとMarionetteモジュールによるバックボーンコードの構造化」の議論に基づいています。ある意味では、以下で説明するようにMarionette.jsとRequire.jsを併用することができます。

以下の例は、オンラインで見つかる小さなライブラリマネージャーのアプリ(サンプル)です。@https://github.com/srihari-sridharan/LibraryManagement以下のコードは、アプリケーションオブジェクトを作成し、初期化後に書籍のリストをレンダリングします。ここでそれを見つけて下さい - https://github.com/srihari-sridharan/LibraryManagement/blob/master/app/js/app.js

define([ 
    'marionette', 
    'modules/config/marionette/regions/dialog'], function (Marionette) { 

    // Create the application object 
    var LibraryManager = new Marionette.Application(); 

    // Add regions to the application object 
    LibraryManager.addRegions({ 
     //Header 
     headerRegion: "#header-region", 
     //Main 
     mainRegion: "#main-region", 
     //Footer 
     footerRegion: "footer-region", 
     //Overlay Dialog 
     dialogRegion: Marionette.Region.Dialog.extend({ 
      el:"#dialog-region" 
     }) 
    }); 

    // Subscribe to Initialize After event. 
    LibraryManager.on('initialize:after', function() { 
     if(Backbone.history){ 
      require(['modules/books/booksModule', 'modules/about/aboutModule'], function(){ 
       Backbone.history.start();  
       if(LibraryManager.getCurrentRoute() === ''){ 
        LibraryManager.trigger("books:list"); 
       }      
      }); 
     } 
    }); 

    // Return the application object. 
    return LibraryManager; 
}); 

次は、我々は機能に基づいてモジュール/サブモジュールを定義します。これにはモジュール固有のルーターもあり、コントローラーを配線してルートを処理します。コントローラーへの呼び出しが必要であることに注意してください。このコードは、最後に私たちが望む、モデルやコントローラの定義を持っているhttps://github.com/srihari-sridharan/LibraryManagement/blob/master/app/js/modules/books/booksModule.js

define(['app'], function (LibraryManager) { 
    // Define a new module for Books - BooksModule 
    LibraryManager.module('BooksModule', function (BooksModule, LibraryManager, Backbone, Marionette, $, _) { 

     BooksModule.startWithParent = false; 

     BooksModule.onStart = function() { 
      console.log('Starting BooksModule.'); 
     }; 

     BooksModule.onStop = function() { 
      console.log('Stopping BooksModule.'); 
     }; 

    }); 

    // Define a new module for a Router specific to BooksModule 
    LibraryManager.module('Routers.BooksModule', function (BooksModuleRouter, LibraryManager, Backbone, Marionette, $, _) { 

     BooksModuleRouter.Router = Marionette.AppRouter.extend({ 
      appRoutes: { 
       'books': 'listBooks', 
       'books(?filter:=criterion)': 'listBooks', 
       'books/:id': 'showBook', 
       'books/:id/edit': 'editBook' 
      } 
     }); 

     var executeAction = function (action, arg) { 
      LibraryManager.startSubModule('BooksModule'); 
      action(arg); 
      LibraryManager.execute('set:active:header', 'books'); 
     }; 

     var API = { 
      // This is where we are using/referring to our controller 
      listBooks: function (criterion) { 
       require(['modules/books/list/listController'], function (ListController) { 
        executeAction(ListController.listBooks, criterion); 
       }); 
      }, 

      showBook: function (id) { 
       require(['modules/books/show/showController'], function (ShowController){ 
        executeAction(ShowController.showBook, id); 
       }); 
      }, 

      editBook: function (id) { 
       require(['modules/books/edit/editController'], function (EditController) { 
        executeAction(EditController.editBook, id); 
       }); 
      } 

     }; 

     // Navigating routes. 
     LibraryManager.on('books:list', function() { 
      LibraryManager.navigate('books'); 
      API.listBooks(); 
     }); 

     LibraryManager.on('books:filter', function(criterion) { 
      if(criterion){ 
       LibraryManager.navigate('books?filter=' + criterion); 
      } 
      else{ 
       LibraryManager.navigate('books'); 
      } 
     }); 

     LibraryManager.on('book:show', function (id) { 
      LibraryManager.navigate('books/' + id); 
      API.showBook(id); 
     }); 

     LibraryManager.on("book:edit", function(id){ 
      LibraryManager.navigate('books/' + id + '/edit'); 
      API.editBook(id); 
     }); 

     LibraryManager.addInitializer(function() { 
      new BooksModuleRouter.Router({ 
       controller: API 
      }); 
     }); 
    }); 

    return LibraryManager.BooksModuleRouter; 
}); 

に存在しています。これらの定義は、モジュール/サブモジュールオブジェクトに関連付けられます。

ビューコードを以下に示します。 .extend()メソッドを見てください。それらは、BooksModule.List.Viewサブモジュールに添付された変数に割り当てられます。 https://github.com/srihari-sridharan/LibraryManagement/blob/master/app/js/modules/books/list/listView.js

define(['app', 
     'tpl!modules/books/list/templates/layout.html', 
     'tpl!modules/books/list/templates/panel.html', 
     'tpl!modules/books/list/templates/none.html', 
     'tpl!modules/books/list/templates/list.html', 
     'tpl!modules/books/list/templates/listItem.html'], 
    function (LibraryManager, layoutTemplate, panelTemplate, noneTemplate, listTemplate, listItemTemplate) { 

     LibraryManager.module('BooksModule.List.View', function(View, LibraryManager, Backbone, Marionette, $, _) { 

      View.Layout = Marionette.Layout.extend({ 

       template: layoutTemplate, 

       regions:{ 
        panelRegion: '#panel-region', 
        booksRegion: '#books-region' 
       } 

      }); 

      View.Panel = Marionette.ItemView.extend({ 
       // More code here! 
      }); 

      View.Book = Marionette.ItemView.extend({     
       // More code here! 
      }); 

      var NoBooksView = Marionette.ItemView.extend({ 
       template: noneTemplate, 
       tagName: "tr", 
       className: "alert" 
      }); 

      View.Books = Marionette.CompositeView.extend({ 
       // More code here! 
      }); 
     }); 
    return LibraryManager.BooksModule.List.View; // Return the definition. 
}); 

コントローラコードを以下に示します。これはbooksModule.jsのコードから呼び出されます。コントローラー定義は、BooksModule.Listサブモジュールに関連付けられています。

define(['app', 'modules/books/list/listView'], function (LibraryManager, View) { 

    LibraryManager.module('BooksModule.List', function (List, LibraryManager, Backbone, Marionette, $, _) { 

     List.Controller = { 

      listBooks: function (criterion) { 

       require(['common/views', 'entities/book'], function (CommonViews) { 

        var loadingView = new CommonViews.Loading(); 
        LibraryManager.mainRegion.show(loadingView); 

        var fetchingBooks = LibraryManager.request('book:entities'); 
        var booksListLayout = new View.Layout(); 
        var booksListPanel = new View.Panel(); 

        require(['entities/common'], function (FilteredCollection) { 

         $.when(fetchingBooks).done(function (books) { 
          // More code here! 
          }); 

          if(criterion){ 
           filteredBooks.filter(criterion); 
           booksListPanel.once('show', function() { 
            booksListPanel.triggerMethod("set:filter:criterion", criterion); 
           }); 
          } 

          var booksListView = new View.Books({ 
           collection: filteredBooks 
          }); 

          booksListPanel.on('books:filter', function (filterCriterion) { 
           filteredBooks.filter(filterCriterion); 
           LibraryManager.trigger("books:filter", filterCriterion); 
          }); 

          booksListLayout.on("show", function(){ 
           booksListLayout.panelRegion.show(booksListPanel); 
           booksListLayout.booksRegion.show(booksListView); 
          }); 

          booksListPanel.on('book:new', function() { 

           require(["modules/books/new/newView"], function (NewView) { 
             // More code here! 
            }); 

            LibraryManager.dialogRegion.show(view); 
           }); 
          }); 

          booksListView.on('itemview:book:show', function (childView, model) { 
           LibraryManager.trigger("book:show", model.get('id')); 
          }); 

          booksListView.on('itemview:book:edit', function(childView, model) { 
           require(['modules/books/edit/editView'], function (EditView) { 
            // More code here! 
            LibraryManager.dialogRegion.show(view); 
           }); 
          }); 

          booksListView.on("itemview:book:delete", function (childView, model) { 
           model.destroy(); 
          }); 

          LibraryManager.mainRegion.show(booksListLayout); 

         }); 

        }); 

       }); 

      } 

     } 

    }); 

    return LibraryManager.BooksModule.List.Controller; // Return the definition. 
}); 

したがって、require.jsモジュールとマリオネットモジュールは共存できます。以下は利点です。

  • ソースコードの整理がより明確になり、懸念がより明確になります。
  • モジュールの開始および終了メソッドは、オブジェクトを初期化およびクリーンアップするための手段を提供します。
  • モジュールとサブモジュールとして機能とサブ機能をモデル化すると、メモリ内に存在するものとそうでないものを細かく制御できます。
  • また、モジュール定義を複数のファイルに分割することもできます。

あなたの考えを投稿してください。読んでくれてありがとう。

PS:上記の観点に基づいて、以下のあなたの例に変更を見つけてください:

require([ "jquery", "underscore", "backbone", "marionette" ], 
function($, _, Backbone, Marionette) { 
    App.module("FirstView", function(FirstView, App, Backbone, Marionette, $, _) { 
     FirstView.View = Marionette.ItemView.extend({ 
      //define view stuff in here 
     }); 

     return FirstView.View; 
    }); 
}); 
関連する問題