2013-03-08 13 views
26

Quale sarebbe il modo migliore per dividere l'applicazione AngularJS in pezzi/moduli più piccoli? Ad esempio se ho un post sul blog e i commenti abilitati per questo, penso che potrei suddividerlo in moduli come "post" e "commenti" (?) (Forse non è l'esempio migliore, ma l'idea è di dividere l'applicazione logica in moduli separati piuttosto che costruire un'enorme one-module-app).Come suddividere l'applicazione AngularJS in moduli più piccoli e gestire correttamente il routing?

Ho provato a eseguire il bootstrap di entrambi i moduli nei nodi DOM separati e utilizzare il routing in entrambi i moduli di conseguenza. Ci sono pochi problemi:

  • Come applicazione "pagina singola" I'm bootstrapping modulo commenti da utilizzare anche in prima pagina anche se non è utilizzato lì.
  • Poiché non sono in grado di utilizzare più ng-view all'interno di ng-app, sono obbligato a scrivere tutti i wrapper per i miei moduli nella vista index.html e riavviarli? Dovrebbe essere così? Sembra un po 'sbagliato. Come/dove dovrei effettuare il bootstrap di quelli?
  • Ci sono suggerimenti per il routing? Devo diffondere quelli nei moduli o dovrei combinarli tutti insieme in qualche modo? (creare un modulo "blog" per includere i moduli "post" e "commenti" come dipendenze renderebbe ancora difficile definire ad esempio l'instradamento "/ 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']); 

risposta

2

stiamo facendo qualcosa di simile con un'applicazione portale e sub-apps. Alcune cose che abbiamo scoperto:

  1. Solo una "app" può avere percorsi e routeParams. Per questo motivo, se la "subapp" ha bisogno di accedere a $ routeParams, devi andare "old school" per l'analisi degli URL o utilizzare un servizio eventi.
  2. A proposito di eventi, non è disponibile alcun servizio Angolare per le applicazioni per comunicare, quindi è necessario eseguire il rollover del proprio servizio eventi parlando all'ambito principale di entrambe le app e iniettandolo in entrambe le app.
  3. Non riesco a vedere dove abbiamo usato ng-view per la "subapp". Apparentemente il bootstrap direttamente su un elemento funziona in modo simile.
  4. Poiché solo un'app può avere percorsi, le app devono essere riavviate in ordine. Quindi, qualcosa di simile:

    $(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

Ciao! Grazie per aver risposto. Penso di essere riuscito ad accedere a $ routeParams da una "sub-app", ma intendi per chiarezza di mantenere anche tutti i percorsi all'interno di un'applicazione principale? (Oppure ho solo frainteso cosa intendevi?). Un buon punto sul servizio dell'evento, penso che sia qualcosa che potrei aver bisogno di implementare anche io. Inoltre intendi che non stai usando più ng-view, ma piuttosto usi ng-include o qualcosa del genere? – acoder

21

vorrei dividere l'applicazione in "moduli" e vista questi sub moduli.

Quindi utilizzare $ routeProvider per passare da una vista all'altra. Definisco la diversa configurazione di routing in ogni modulo.

Se ho bisogno di ulteriori sottomoduli, li carico con 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>' 
    }); 
}]); 

Ho creato un piccolo repository su github per spiegare questo.

+0

Grazie per aver risposto! Quindi, fondamentalmente l'idea è di costruire un modulo app principale che sia bootstrap e altri "moduli di visualizzazione" come dipendenze per quello. Distribuendo le informazioni di routing in questi moduli e invece di affidarsi a più ng-view e caricare in automatico moduli diversi uno per uno, questa soluzione si basa molto su ng-include. Ciò non trarrebbe un vantaggio dalla ng-view e dal controller $ routeProviders e dalla gestione dei template tanto, ma rende i moduli più liberamente utilizzabili all'interno dell'applicazione (diversi luoghi/percorsi/viste ...) Se ho capito bene? – acoder

+0

Ci scusiamo per il ritardo. IMHO AngularJS non supporta più direttive ng-view fuori dalla scatola. Se hai bisogno di più direttive ng-view, guarda questo: https://groups.google.com/forum/?fromgroups=#!topic/angular/ayG1hCUOfX0 – S3PP3L

+0

questo è un ottimo schema, mi chiedo se c'è un modo per definire un modulo usando il wrapper commonjs semplificato .. – andrean

6

È possibile definire percorsi nei sottomoduli:

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

Ho anche scritto a blog post su questo argomento.

Problemi correlati