2013-03-08 10 views
26

Jaki byłby najlepszy sposób na podzielenie aplikacji AngularJS na mniejsze elementy/moduł? Na przykład, jeśli mam wpis na blogu i dodawanie komentarzy do tego, myślę, że mógłbym podzielić go na moduły takie jak "posty" i "komentarze" (?) (Może nie jest to najlepszy przykład, ale chodzi o podzielenie aplikacji logiki na osobne moduły, zamiast budować ogromną aplikację z jednym modułem).Jak podzielić aplikację AngularJS na mniejsze moduły i poprawnie zarządzać routingiem?

Próbowałem załadować oba moduły w oddzielnych węzłach DOM i użyć odpowiednio routingu w obu modułach. Jest kilka problemów:

  • Jako aplikacja "pojedyncza strona" ładuję moduł komentarzy do użycia nawet na pierwszej stronie, nawet jeśli nie jest tam używany.
  • Ponieważ nie jestem w stanie używać wielu widoków ng wewnątrz aplikacji ng, jestem zmuszony do napisania wszystkich wrapperów dla moich modułów w widoku index.html i załadowania ich? Czy powinno tak być? Wydaje się trochę nie tak. Jak/gdzie powinienem je uruchomić?
  • Czy są jakieś wskazówki dotyczące trasy? Czy powinienem je rozłożyć w modułach, czy też powinienem je w jakiś sposób połączyć? (Utworzenie jednego modułu "blog" w celu włączenia modułów "posty" i "komentarze" jako zależności nadal utrudnia określenie np. trasy "/ post /: id"?)

index.html

<div class="post"><ng-view></ng-view></div> 
<div class="comments"><ng-view></ng-view></div> 

javascript.js

angular.module('posts', []).config(['$routeProvider', function ($routeProvider) { 
    $routeProvider 
    .when('/', { 
     'template': 'Showing all the posts', 
     'controller': 'postCtrl 
    }) 
    .when('/post/:id', { 
     'template': 'Showing post :id', 
     'controller': 'postCtrl 
    }); 
}]); 

angular.module('comments', []).config(['$routeProvider', function ($routeProvider) { 
    $routeProvider.when('/post/:id', { 
     'template': 'Showing post :id comments', 
     'controller': 'CommentsCtrl' 
    }); 
}]); 

angular.bootstrap($('.post'), ['posts']); 
angular.bootstrap($('.comments'), ['comments']); 

Odpowiedz

2

robimy coś podobnego z aplikacją portal i sub-apps. Kilka rzeczy, które odkryliśmy:

  1. Tylko jedna "aplikacja" może mieć trasy i trasęParams. Z tego powodu, jeśli "sub-aplikacja" potrzebuje dostępu do $ routeParams, musisz przejść do "starej szkoły" w celu analizy adresu URL lub skorzystać z usługi wydarzenia.
  2. Mówiąc o zdarzeniach, nie ma żadnej usługi Angular dla aplikacji do komunikacji, więc będziesz musiał przetasować własną usługę zdarzeń rozmawiając z zakresem głównym dla obu aplikacji i wstrzyknąć ją do obu aplikacji.
  3. Nie widzę, gdzie użyliśmy ng-view dla "sub-app". Podobno bootstrapping bezpośrednio do elementu działa podobnie.
  4. Ponieważ tylko jedna aplikacja może mieć trasy, aplikacje powinny być ładowane w kolejności. Więc coś takiego:

    $(function() { 
    
        $.when(angular.bootstrap($('.post'), ['posts'])).done(function() { 
         console.log('POSTS: bootstrapped'); 
    
         //Manually add the controller to the comments element. (May or may not be 
         //necessary, but we were doing something that required it to work.) 
         $('.comments').attr('ng-controller', 'CommentsCtrl'); 
    
         $.when(angular.bootstrap($('.comments'), ['comments'])).done(function() { 
          console.log('COMMENTS: bootstrapped'); 
         }); 
    
        }); 
    }); 
    
+0

Witam! Dzięki za odpowiedź. Myślę, że udało mi się uzyskać dostęp do $ routeParams z "sub-app", ale czy dla jasności powinieneś zachować wszystkie trasy wewnątrz jednej głównej aplikacji? (Czy też źle zrozumiałem, co miałeś na myśli ...) Dobra uwaga odnośnie usługi eventowej, myślę, że to jest coś, co może być potrzebne do wdrożenia. Czy masz na myśli, że nie używasz wielu widoków, ale raczej używasz ng-include lub czegoś takiego? – acoder

21

chciałbym podzielić aplikację w „Widok” i modułów podrzędnych tych modułów.

Następnie używam opcji $ routeProvider, aby przełączać widoki. Definiuję różne konfiguracje routingu w każdym module.

Jeśli potrzebuję dalszych submodułów, ładuję je za pomocą ng-include.

/* App Module */ 

angular.module('MyApp', ['MyApp.home', 'MyApp.blog']) 
.config(function myAppConfig ($routeProvider) { 
    'use strict'; 
    $routeProvider.otherwise({ redirectTo: '/home' }); 
}); 


/* home Module */ 

angular.module('MyApp.home', []) 
.config(['$routeProvider', function config($routeProvider) { 
    $routeProvider.when('/home', { 
    controller: 'HomeController', 
    template: '<p>This is my Home</p>' 
    }); 
}]); 

Stworzyłem małe repozytorium na github, aby to wyjaśnić.

+0

Dzięki za odpowiedź! Więc zasadniczo chodzi o to, aby zbudować jeden główny moduł aplikacji, który jest bootstrapped i inne "moduły widoku" jako zależności. Rozprzestrzeniając informacje o routingu w tych modułach i zamiast polegać na wielu widokach i uruchamiając różne moduły jeden po drugim, rozwiązanie to opiera się głównie na ng-include. Nie skorzystałoby to tak bardzo z obsługi kontrolerów ng-view i $ routeProviders i szablonów, ale sprawia, że ​​moduły są swobodnie używane w całej aplikacji (różne miejsca/trasy/widoki). Jeśli dobrze zrozumiałem? – acoder

+0

Przepraszamy za opóźnienie. IMHO AngularJS nie obsługuje już wielu dyrektyw ng-view. Jeśli potrzebujesz wielu dyrektyw widoku, spójrz na to: https://groups.google.com/forum/?fromgroups=#!topic/angular/ayG1hCUOfX0 – S3PP3L

+0

to świetny wzór, zastanawiam się, czy jest sposób zdefiniować moduł przy użyciu uproszczonego opakowania commonjs. – andrean

6

można określić trasy w submodułów:

angular.module('app', ['ngRoute', 'app.moduleX']) 
.config(function($routeProvider, $locationProvider) { 
    $routeProvider.when('/home', { 
    templateUrl: 'partials/home.html', 
    controller: 'HomeCtrl' 
    }); 

    //Handle all exceptions 
    $routeProvider.otherwise({ 
    redirectTo: '/home' 
    }); 
}) 

angular.module('app.moduleX', []).config(function($routeProvider) { 
    $routeProvider.when('/settings', { 
    templateUrl: 'partials/settings.html', 
    controller: 'SettingsCtrl' 
    }); 
}) 

Pisałem także a blog post o tym temacie.

Powiązane problemy