Scalable Angular SPA Architecture

0

Sto sviluppando una Angular SPA e sono attualmente in fase di progettazione. Ho creato un'architettura di esempio che sto progettando di utilizzare nella mia SPA, ma otterrei un feedback perché voglio che l'architettura sia scalabile e mantenibile. Ho testato questa architettura e funziona fino ad ora.

Architettura corrente:

  1. Ho il modulo "Main" dove risiede il mio ngRoute e da lì controllerò i percorsi delle mie app.
  2. Ho creato un modulo separato per ciascuna funzionalità distinta della mia app, ad esempio (DashboardCtrl, AdminCtrl, blogCtrl, ecc.)
  3. Essendo una SPA, è meglio avviare solo 1 app angolare nella pagina html I bootstrap ( ng-app="mainApp" ) sul front-end. Ma aggiungo tutti gli altri moduli all'interno del modulo principale come dipendenze.

Importante:

Essendo una SPA, sto utilizzando la proprietà resolve di ngRoute per ottenere i dati dal server prima di caricare la vista e quindi passare i dati risolti a un controller specifico responsabile di tale funzionalità.

Modulo principale:

var app = angular.module('app',['ngRoute','app.blog','routeService']);

app.config(function($routeProvider) {
    $routeProvider

        // route for the home page

        .when('/', {
            templateUrl: '/overview.html',
            controller: 'mainCtrl'
        })

        // route for the about page
        .when('/blog', {
            templateUrl : '/blog.html',
            controller  : 'blogCtrl',
            resolve: {

                myDta: function(dataFetch){
                    return dataFetch.getProposals();
                }}
        })

        // route for the contact page
        .when('/bios', {
            templateUrl : 'bios.html',
            //controller  : 'contactController'
        });


});

 app.run(['$rootScope', function($root) {

 $root.$on('$routeChangeStart', function(e, curr, prev) { 
   if (curr.$$route && curr.$$route.resolve) {
    // Show a loading message until promises are not resolved
    $root.loadingView = true;
   }
 });

 $root.$on('$routeChangeSuccess', function(e, curr, prev) { 
   // Hide loading message
   $root.loadingView = false;
 });

 }]);


   app.controller('mainCtrl',function($scope){

 });

Modulo Blog:

var blog = angular.module('app.blog',[]);

proposal.controller('blogCtrl', function($scope, myDta){
  // This is where I will handle all the logic for blogs. Will have functions calling blog service which will call the server and GET or POST data.
  $scope.prop = myDta;
});

HTML:

<html lang="en" ng-app="app">
 <script type="text/javascript" src="./js/app.js"></script>
 <script type="text/javascript" src="./js/blog.js"></script>
 <script type="text/javascript" src="services.js"></script>

Pensi che l'architettura o la struttura siano abbastanza buone da essere messe in produzione? La mia app cresce lentamente, aggiungendo molte più funzionalità, quindi voglio assicurarmi che la struttura che creo sia gestibile e scalabile.

    
posta Lorenzo von Matterhorn 19.08.2016 - 10:15
fonte

2 risposte

1

Non hai qualcosa di sbagliato qui, se davvero ti aspetti che il tuo codice base cresca molto dovresti esplodere la configurazione del router in ogni modulo.

Ciò significa che il modulo app.blog dovrebbe dichiarare se stesso la rotta /blog e così via.

Lo stesso per i modelli, dovresti almeno avere una sottocartella dedicata per il tuo modulo per avere qualcosa di simile

  • blog / blog.html
  • bios / bios.html

Perché nel tempo avrai più di un modello per modulo.

Infine, non dimenticare che alcuni modelli non dipenderanno dalla funzionalità, ma da componenti / direttive, quelli dovrebbero essere isolati in moduli specifici se non sono specifici per un solo modulo.

Per la produzione, di solito si minimizza il codice per avere alla fine solo un singolo file da caricare. Questo diminuisce molto il primo tempo di caricamento della tua pagina.

EDIT: ecco alcuni esempi:

app.js

var app = angular.module('app',['ngRoute','app.blog','routeService']);

app.config(function($routeProvider) {
    $routeProvider

        // route for the home page

        .when('/', {
            templateUrl: '/overview.html',
            controller: 'mainCtrl'
        })  // i don' know about this one, maybe move it under blog 
        // or in another module if it's not specific to blog
        .when('/bios', {
            templateUrl : 'bios.html',
            //controller  : 'contactController'
        });





});

Blog / blogs.js

angular.module('app.blog',['routeService'])
.config(['$routeProvider', function($routeProvider){

// route for the about page
        $routeProvider.when('/blog', {
            templateUrl : '/blog/blog.html',
            controller  : 'blogCtrl',
            resolve: {

                myDta: function(dataFetch){
                    return dataFetch.getProposals();
                }}
        })

  }])

Blog / blog.ctrl.js

angular.module('app.blog').controller('blogCtrl', ...);

Nota: Solitamente ogni controller / servizio è suddiviso in un proprio file.

    
risposta data 24.08.2016 - 09:31
fonte
0

Forse non è una risposta completa. Ma quello che mi ha davvero aiutato è stato Angular StyleGuide di John Papa.

Nel complesso è un ottimo inizio ma ho alcune osservazioni:

Controller As

Prova a utilizzare il controller come sintassi. in particolare quando si utilizzano viste nidificate. In questo modo puoi fare riferimento a variabili e funzioni su un controller specifico.

<div ng-controller="BookController as book">
   {{ book.title}}
 </div>

Questa parola chiave

Se si utilizza il controller come sintassi, il controller deve utilizzare questa parola chiave anziché $ scope.

function BookController() {
   var vm = this;
   vm.title= {};
   vm.deleteBook= function() { };

}

Iniezione

Quando si usa la minification si ottengono errori sui parametri di iniezione necessari per specificare manualmente i parametri.

angular
.module('app')
.controller('BookController', BookController);

BookController.$inject = ['books', 'data'];

function BookController(books,data) {}

funzioni autonome anonime

Prova a dare a ogni controller, percorso, configurazione in un file separato in modo da poter utilizzare le funzioni anonime autoesposte. Racchiudere ogni controller, percorso, ecc. Come questo esempio. Consulta questa risposta per maggiori informazioni .

(function () {
   'use strict';
    angular.module('app').controller('BookController', BookController);
})();
    
risposta data 24.08.2016 - 09:22
fonte

Leggi altre domande sui tag