2015-04-23 9 views
5

Ich bin dabei, eine Architektur einer ziemlich komplexen Anwendung basierend auf eckigen skizzieren. Also habe ich mit dem Angular-Seed-Projekt angefangen und es scheint ein guter Ausgangspunkt zu sein. Was mich stört ist, dass eckige Apps von Natur aus alles im Voraus laden. Mit Script Loadern scheint es keinen sauberen Weg zu geben.lazy Laden von Komponenten in eckig mit browserify

Ich kam aus einem backbone.js Hintergrund und da war es ruhig gerade, um die require.js für das faule Laden basierend auf den Router-Callbacks zu verwenden. In Winkel Routen sind so etwas wie die folgende Bedeutung haben:

// Declare app level module which depends on views, and components 
angular.module('myApp', [ 
    'ngRoute' 
]). 
config(['$routeProvider', function($routeProvider) { 
    $routeProvider.when({templateURL:'../tmpl.html',controller:'view1Ctrl'}) 
.when({templateURL:'../tmpl.html',controller:'view1Ctrl'}) 
.otherwise({redirectTo: '/view1'}); 
}]); 

jetzt hier, $routeProvider.when({templateURL:'../tmpl.html',controller:'view1Ctrl'}) Ich mag träge würde den Controller und die Vorlage laden. Ich war so etwas wie zu verwenden versucht:

$routeProvider.when({templateURL:'../tmpl.html',controller:require('view1Ctrl'}) 

mit browserify aber dann ist es scheint nicht sauber zu sein und nicht einmal mit erfordern. Ich weiß, dass diese Frage mehrmals auf SO gestellt wurde, aber ich habe keine eindeutige Antwort darauf gefunden.

Meine Präferenz hier ist die Verwendung der browserify, wie es die beliebten cjs-Module im Browser unterstützt.

+0

Wie Sie gesagt haben, aufgrund der Natur von Angularjs es "nicht-hacky Weg" zu tun, das ist. Sie müssen '$ controllerProvider.register',' $ provider.factory' und '$ compileProvider.directive' an irgendeiner Stelle im Run-Status verwenden. Aber es ist ein Hack. :( –

+0

Auch ich denke, das ist verwandt: http://stackoverflow.com/questions/21742495/lazy-loading-of-angular-component-scripts-when-changing-states –

Antwort

3

Ich bin nicht sicher, wie dies mit Browserify zu tun ist, wie ich es selbst nie versucht habe, aber ich würde Ihnen wärmstens empfehlen, sich in ocLazyLoad.

Als eigenständiger Dienst funktioniert es Wunder mit dem Laden von Dateien (json, css, js, Vorlagen - Sie nennen es) und injizieren es in Ihre bereits laufende eckige Anwendung.

Mit diesem gesagt, es funktioniert noch besser (IMO) gekoppelt mit einem Router (der Standard eckigen, oder UI-Router).

Es gibt einige "Seed-Projekte", die zeigen, wie man es mit ocLazyLoad in Verbindung mit SystemJS machen kann.


Aber Sie haben nicht einmal das brauchen.

Wenn Sie mit ui-Router gehen, ui-Router-Extras und ocLazyLoad Sie so etwas wie diese zusammen zu faul Lastzustände setzen können:

main.js

/** 
* Inject the needed dependencies into our main module. 
*/ 
var main = angular.module('main', [ 'ui.router', 'ct.ui.router.extras.future', 'oc.lazyLoad' ]); 

/** 
* Define the lazy loaded states. 
*/ 
main.constant('lazyLoadedStates', [ 
    { 
    name: 'about', 
    url: '/about', 
    type: 'lazy', 
    src: [ 
     '/path/to/about.module.js', 
     '/path/to/AboutController.js' 
    ] 
    } 
]); 

/** 
* Setup the behaviour for when we hit a futureState with the 'lazy' 
* type. 
* 
* 1. Setup a deferred object. 
* 2. Resolve the promise when every file defined in the futureState.src has been loaded. 
* 3. Return the promise. 
*/ 
main.config(function ($futureStateProvider, lazyLoadedStates) { 
    $futureStateProvider.stateFactory('lazy', function ($q, $ocLazyLoad, futureState) { 
    var deferred = $q.defer(); 

    $ocLazyLoad.load(futureState.src).then(function() { 
     deferred.resolve(); 
    }); 

    return deferred.promise; 
    }); 

    lazyLoadedStates.forEach($futureStateProvider.futureState); 
}); 

Das ist das 'Framework' aus dem Weg - jetzt müssen Sie nur weitere Module hinzufügen, mit mehr Code und eine echte Zustandsdefinition mit der übereinstimmen Dummy eins in der lazyLoadedStates Konstante.

über.module.js

/** 
* Setup the _real_ '/about' state in this lazy loaded file. 
*/ 
angular.module('about', []).config(function ($stateProvider) { 
    $stateProvider.state('about', { 
    url: '/about', 
    controller: 'AboutController', 
    template: 'some_template.html' 
    }); 
}); 

AboutController.js

/** 
* Register the AboutController in a lazy loaded file. This could be done in about.module.js aswell, 
* but we'll do it here to separate stuff and showcase loading of multiple files. 
*/ 
angular.module('about').controller('AboutController', function ($state) { 
    console.log('Im on a lazy loaded state!', $state.current); 
}); 

Ich hoffe, dass gibt Ihnen die ungefähre Vorstellung davon, wie faul geladenen Staaten zur Einrichtung in Angular. Ich habe noch einen einfacheren Weg gefunden, dies zu tun, aber ich bin sicher, es gibt Artikel da draußen, wie man den UI-Router (oder den Standard-Winkelrouter) mit einem anderen 'Lazy Loader' koppelt.

Doc Links: