2014-05-14 13 views
21

Sono molto nuovo per Angular. Ho visto alcuni tutorial e letto alcuni documenti. Ora sto iniziando a sporcarmi le mani. Sto provando a creare una semplice app per dispositivi mobili a una pagina con più visualizzazioni e un pulsante successivo \ indietro per controllare ciascuna vista. Sto usando la libreria UI di Angular Mobile, ma non dovrebbe importare molto.AngularJS - caricamento dinamico di JS esterno in base a percorsi

Il mockup base è la seguente:

<html> 
    <head> 
     <link rel="stylesheet" href="mobile-angular-ui/dist/css/mobile-angular-ui-base.min.css"> 
     <link rel="stylesheet" href="mobile-angular-ui/dist/css/mobile-angular-ui-desktop.min.css"> 

     <script src="js/angular/angular.min.js"></script> 
     <script src="js/angular/angular-route.min.js"></script> 
     <script src="mobile-angular-ui/dist/js/mobile-angular-ui.min.js"></script> 

     <script src="app/app.js"></script> 
     <script src="app/firstController.js"></script> 
     <script src="app/secondController.js"></script> 
     <script src="app/thirdController.js"></script> 

    </head> 

    <body ng-app="demo-app"> 
     <div ng-view></div> 

     <div ng-controller="nextBackController" class="navbar navbar-app navbar-absolute-bottom"> 
      <div class="btn-group justified"> 
       <a href="#/" class="btn btn-navbar btn-icon-only"><i class="fa fa-home fa-navbar"></i></a> 
       <a href="#/second" class="btn btn-navbar btn-icon-only"><i class="fa fa-list fa-navbar"></i></a> 
      </div> 
     </div> 

    </body> 


</html> 

App.js è la seguente:

var app = angular.module('demo-app', [ 
    "ngRoute", 
    "mobile-angular-ui" 
]); 

app.config(function($routeProvider) { 
    $routeProvider.when('/', { controller: "firstController", 
          templateUrl: "views/first.html"}); 
    $routeProvider.when('/', { controller: "secondController", 
          templateUrl: "views/first.html"}); 
    $routeProvider.when('/', { controller: "thirdController", 
          templateUrl: "views/first.html"}); 
}); 

controllers = {}; 

controllers.nextBackController = function($scope, $rootScope) { 
    //Simple controller for the next, back buttons so we just put it in app.js 
}; 

app.controller(controllers); 

firstController.js conterrà qualcosa di simile a:

controllers.firstController = function($scope) { 
    //Do our logic here!!! 
}; 

Il problema è se si nota nella parte superiore della pagina HTML devo caricare tutti i controller in. Questo non è scalabile. Voglio che ogni controller sia nel proprio file JS e non debba caricarlo staticamente poiché l'utente potrebbe non aver mai nemmeno bisogno di quel controller. C'è un modo per caricare dinamicamente il file JS effettivo quando si cambiano le rotte? oppure posso attaccare un tag script nella parte superiore del mio "first.html", "second.html", ecc.

+0

Che cosa si vuole fare è esattamente come lo sto facendo ora. Ogni controller è nel proprio file JS. Il modo in cui li carico è: 'app.controller ("ControllerName", function() {/ * Codice controller * /}); '(dato che hai memorizzato il tuo modulo app nella variabile globale' app'). Pertanto, non uso 'app.controller (controller)' – Ian

+1

@lan La mia domanda è come posso inserire i file JS del controller come ho bisogno di loro invece di metterli tutti nella parte superiore della pagina principale in tag di script. Diciamo che ho 20 controller, uno per ogni componente. Ciò renderà il tempo di caricamento orribile. Voglio solo entrare in .JS di firstController quando \ se ne ho bisogno. O l'angolare cerca automaticamente il file JS ?? – user3621014

+0

Soprattutto per le soluzioni mobili, è necessario concatenare meglio tutti gli script, ridimensionarli e caricare solo un file javascript. Nella maggior parte dei casi questo sarà più veloce del caricamento di molti piccoli file. La latenza è il tuo nemico. – hgoebl

risposta

1

Non sono sicuro di come funzioni in angolare standard, tuttavia, è possibile utilizzare angolare-ui- router:

"Controllers are instantiated on an as-needed basis, when their corresponding 
scopes are created, i.e. when the user manually navigates to a state via a URL, 
$stateProvider will load the correct template into the view, then bind the 
controller to the template's scope." 

https://github.com/angular-ui/ui-router/wiki

+0

Sono sicuro che questo è esattamente il modo in cui funziona anche il normale routing angolare. Il punto dell'OP è che non vogliono nemmeno caricare il controller (file) finché non è necessario ... e non penso che l'ui-router faccia qualcosa di diverso rispetto a quello – Ian

1

RequireJS può essere davvero utile in questo caso. È possibile dichiarare le dipendenze dei file JS utilizzando RequireJS.

È possibile consultare il tutorial this semplice.

5

A meno che la vostra applicazione è MASSIVE, si dovrebbe davvero evitare di servire piccoli file js singolarmente. Questo rallenterà sensibilmente la tua app, anche se dovessi trovare un modo per scaricare i file in modo pigramente come necessario nella tua domanda.

Un modo molto migliore per eseguire questa operazione (e il modo utilizzato e suggerito dal team di AngularJS) è di avere un PROCESSO COSTRUITO (per questo si dovrebbe usare grunt) concatenare tutti i file javascript e servirli come un'unica app file .js. In questo modo è possibile mantenere una base di codice organizzata con tutti i piccoli file js che si desidera, ma ridurre il recupero di script a una singola richiesta.

+0

Nota che questo non è più il caso con http2, dove in effetti vengono preferiti molti file più piccoli. –

7

Se si ha familiarità con Grunt:

https://github.com/ericclemmons/grunt-angular-templates

Usa Grunt e il compito di compilazione sopra per creare uno .js da tutti i punti di vista. Includere un listener di attività watch su tutti i file html in una directory views.Ogni volta che viene apportata una modifica a qualsiasi vista parziale, viene creata una voce "$ templateCache" con tutto il codice html nel file e un url per l'alias della cache. I percorsi punteranno alle viste parziali allo stesso modo, ma i file html non devono essere presenti. Solo il file .js con i modelli. La bellezza di questo è che si carica una volta ed è disponibile sul lato client per l'intera sessione. Questo riduce le chiamate http e il traffico può essere ridotto alle sole chiamate al servizio web.

Questo è l'esempio di un modello dal link GitHub, sopra:

angular.module('app').run(["$templateCache", function($templateCache) { 
$templateCache.put("home.html", 
// contents for home.html ... 
); 
... 
$templateCache.put("src/app/templates/button.html", 
// contents for button.html 
); 
}]); 

Se non hai familiarità con Grunt

check it out. E 'piuttosto prezioso per automatizzare costruisce, minimizzazione, la concatenazione, transpiling, ecc ...

http://gruntjs.com/

22

Se ho capito bene è necessario caricare script specifici per ogni visualizzazione? Sto condividendo questo frammento di un progetto personale che utilizza ocLazyLoader un plug-in che carica i moduli su richiesta.

var myApp = angular.module("myApp", [ 
"ui.router", 
"oc.lazyLoad", 
]); 

poi nel vostro percorso è possibile caricare file dinamici JS/CSS di conseguenza, in questo esempio sto caricando le UI Select dipendenze del plugin

myApp.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) { 

$stateProvider 

    // State 
    .state('demo', { 
     url: "/demo.html", 
     templateUrl: "views/demo.html", 
     data: {pageTitle: 'demo page title'}, 
     controller: "GeneralController", 
     resolve: { 
      deps: ['$ocLazyLoad', function($ocLazyLoad) { 
       return $ocLazyLoad.load([{ 
        name: 'ui.select', 
// add UI select css/js for this state 
        files: [ 
         'css/ui-select/select.min.css', 
         'js/ui-select/select.min.js' 
        ] 
       }, { 
        name: 'myApp', 
        files: [ 
         'js/controllers/GeneralController.js' 
        ] 
       }]); 
      }] 
     } 
    }) 

Beh spero che questo sia utile ..

+1

Mi hai salvato! Ho avuto un piccolo problema con questo e giocherellando per più di 4 ore, ma la tua soluzione ha funzionato per me. Grazie amico! – Rajkumar

+0

Prego! –

4

Come installare OCLazyLoad.

1. Scaricare ocLazyLoad.jshere

può essere trovato nella cartella 'dist' del repository git. Puoi anche installarlo con bower install oclazyload o npm install oclazyload.

2. Aggiungere il modulo di oc.lazyLoad alla vostra applicazione:

var myApp = angular.module("MyApp", ["oc.lazyLoad"]);

3. Caricare i file JS su richiesta, sulla base di percorsi:

myApp.controller("MyCtrl", function($ocLazyLoad){ 
     $ocLazyLoad.load('testModule.js'); 
    }});` 

Con $ocLazyLoad è possibile caricare moduli angolari, ma se si desidera caricare qualsiasi componente (controller/servizi/filtri/...) senza definire un nuovo modulo è del tutto possibile (assicurati di aver definito questo componente all'interno di un modulo esistente).

Ci sono molti modi per utilizzare $ocLazyLoad per caricare i file, basta scegliere quello che si preferisce.

Inoltre, non dimenticare che se vuoi iniziare e i documenti non sono sufficienti, guarda gli esempi nella cartella "esempi"!

Quick Start

Problemi correlati