2012-07-06 16 views
16

Tôi đang bắt đầu một ứng dụng javascript có quy mô lớn với Marionette. Một ứng dụng rối có một khái niệm về module ứng dụng và RequireJS cũng được sử dụng để phá vỡ mã vào mô-đun,Rô-bốt đường trục và mô-đun RequireJS

Hiện tại tôi có điều này cho sự bắt đầu của ứng dụng của tôi:

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(); 
    }); 
}); 

Nếu tôi muốn thêm một cái nhìn sẽ Tôi làm một cái gì đó như sau trong một tập tin?

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 
     }); 
    }); 

}); 

Tôi không chắc chắn làm thế nào tôi sẽ nhận được mã này để thực sự chạy, bất kỳ sự giúp đỡ được nhiều đánh giá

Trả lời

23

module rối của có nghĩa là để là một lựa chọn đơn giản để RequireJS (và khác) định dạng module. Tôi sẽ không khuyên bạn sử dụng chúng lại với nhau, như đã nêu trong wiki:

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

+0

có ý nghĩa. Cảm ơn! Tôi sẽ sử dụng RequireJS, bởi vì tôi giả định nếu tôi sử dụng mô-đun Marionette tôi phải gắn tất cả các tệp ứng dụng của mình vào các thẻ script trong phần đầu như trong BBCloneMail, tôi đang cố gắng tránh làm điều đó. –

+1

Tôi không khuyên bạn nên sử dụng nhiều thẻ tập lệnh. BBCloneMail không phải là một ví dụ về làm điều đó đúng. :) Các dự án thực tế có các bước xây dựng mà concat & minify. r.js làm cho các mô-đun requirejs, hoặc nó có thể được thực hiện với bất kỳ một số công cụ khác như đường dẫn nội dung Rails hoặc grunt.js hoặc nhiều công cụ khác. –

+2

Đây là liên kết cập nhật để sử dụng Marionette với RequireJS. (Kho lưu trữ github di chuyển.) Https://github.com/marionettejs/backbone.marionette/wiki/Using-marionette-with-requirejs –

4

IMHO Tôi thích khác với quan điểm đã nêu ở trên "module rối của có nghĩa là để là một lựa chọn đơn giản để RequireJS (và khác) định dạng mô-đun. "

Tôi thích vẽ một so sánh giữa mô-đun Require.js và mô-đun Marionette.js với các khái niệm lắp ráp và không gian tên của C#. Các module của Marionette.js giúp chúng tôi nhóm các định nghĩa về các khối xây dựng khác nhau dựa trên chức năng, trong khi Require.js có thể được sử dụng để tải/tiêm phụ thuộc.

Một lần nữa, đây là quan điểm/hiểu biết của tôi (dựa trên các cuộc thảo luận với David Sulc về cuốn sách 'Cấu trúc mã xương sống với RequireJS và Mô-đun rối rắm'), đã giúp tôi thực hiện. Theo cách chúng ta có thể sử dụng Marionette.js và Require.js với nhau như mô tả dưới đây.

Ví dụ bên dưới là một ứng dụng Trình quản lý thư viện nhỏ (mẫu) có thể được tìm thấy trực tuyến @https://github.com/srihari-sridharan/LibraryManagement. Mã dưới đây (bỏ qua các bit và mảnh không đáng kể) tạo đối tượng ứng dụng và hiển thị danh sách sách sau khi khởi tạo. Hãy tìm nó ở đây - 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; 
}); 

Tiếp theo chúng ta định nghĩa module/sub-module dựa trên các chức năng. Điều này cũng sẽ có một bộ định tuyến mô-đun cụ thể và sẽ dây điều khiển và xử lý các tuyến đường. Lưu ý yêu cầu cuộc gọi đến bộ điều khiển. Mã này hiện diện trong 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; 
}); 

Cuối cùng chúng ta có các định nghĩa cho quan điểm, mô hình và các bộ điều khiển của chúng tôi. Các định nghĩa này sẽ được gắn với các đối tượng mô đun/mô đun phụ.

Mã xem được hiển thị bên dưới. Xem các phương thức .extend(). Chúng được gán cho các biến được gắn với mô-đun phụ 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. 
}); 

Mã điều khiển được hiển thị bên dưới. Điều này được gọi từ mã trong booksModule.js. Định nghĩa bộ điều khiển được gắn vào mô-đun phụ 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. 
}); 

Do đó mô-đun require.js và mô-đun marionette có thể cùng tồn tại. Sau đây là những lợi thế.

  • Tổ chức mã nguồn rõ ràng hơn và phân tách mối quan tâm rõ ràng hơn.
  • Phương thức khởi động và dừng mô-đun cung cấp điều kiện để khởi tạo và xóa các đối tượng.
  • Khi bạn mô hình chức năng và chức năng phụ dưới dạng mô-đun và mô-đun phụ, chúng tôi có quyền kiểm soát chi tiết hơn đối với những gì nằm trong bộ nhớ và những gì không nên.
  • Ngoài ra, định nghĩa mô-đun có thể được chia thành nhiều tệp.

Hãy đăng ý kiến ​​của bạn. Cảm ơn vì đã đọc.

PS: Dựa trên quan điểm trên, hãy tìm những thay đổi ví dụ của bạn dưới đây:

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; 
    }); 
});