AngularJS: lazy loading controllers and content

后端 未结 9 854
小鲜肉
小鲜肉 2020-12-02 19:00

In this simplified scenario, I have two files: index.htm, lazy.htm.

index.htm:

var myApp = angular.module(\'myApp\', []);
myApp.controller(\'embed\',         


        
相关标签:
9条回答
  • 2020-12-02 19:45

    You also can use Directives to load your controller!

    A example here:

    https://gist.github.com/raphaelluchini/53d08ed1331e47aa6a87

    0 讨论(0)
  • 2020-12-02 19:48

    You can also use the jquery with the resolve the $routeProvider

    app.js

    /* Module Creation */
    var app = angular.module ('app', ['ngRoute']);
    
    app.config(['$routeProvider', '$controllerProvider', function($routeProvider, $controllerProvider){
    
    /*Creating a more synthesized form of service of $ controllerProvider.register*/
    app.registerCtrl = $controllerProvider.register;
    
    function loadScript(path) {
      var result = $.Deferred(),
      script = document.createElement("script");
      script.async = "async";
      script.type = "text/javascript";
      script.src = path;
      script.onload = script.onreadystatechange = function (_, isAbort) {
          if (!script.readyState || /loaded|complete/.test(script.readyState)) {
             if (isAbort)
                 result.reject();
             else
                result.resolve();
        }
      };
      script.onerror = function () { result.reject(); };
      document.querySelector("head").appendChild(script);
      return result.promise();
    }
    
    function loader(arrayName){
    
        return {
          load: function($q){
                    var deferred = $q.defer(),
                    map = arrayName.map(function(name) {
                        return loadScript('js/controllers/'+name+".js");
                    });
    
                    $q.all(map).then(function(r){
                        deferred.resolve();
                    });
    
                    return deferred.promise;
            }
        };
    }
    
    $routeProvider  
        .when('/', {
            templateUrl: 'views/foo.html',
            resolve: loader(['foo'])
        })
        .when('/bar',{
            templateUrl: 'views/bar.html',
            controller: 'BarCtrl',
            resolve: loader(['bar'])
        })
        .otherwise({
            redirectTo: document.location.pathname
        });
    }]);
    

    /views/foo.html

    <section ng-controller='FooCtrl'>
        {{text}}
    </section>
    

    js/controllers/foo.js

    /*Here we use the synthesized version of $controllerProvider.register 
    to register the controller in view*/
    app.registerCtrl('FooCtrl',function($scope){
        $scope.text = 'Test';
    });
    

    /views/bar.html

    <section>
        {{text2}}
    </section>
    

    js/controllers/bar.js

    app.registerCtrl('BarCtrl',function($scope){
        $scope.text2 = 'Test';
    });
    
    0 讨论(0)
  • 2020-12-02 19:48

    You can have pure AngularJS lazy loading.

    Create "LazyService":

    var ng = angular.module('app');
    
    ng.factory('lazyService', [ '$http', function($http) {
        var jsPath = 'js/${ name }.js';
        var promisesCache = {};
    
        return {
            loadScript: function(name) {
                var path = jsPath.replace('${ name }', name);
                var promise = promisesCache[name];
                if (!promise) {
                    promise = $http.get(path);
                    promisesCache[name] = promise;
    
                    return promise.then(function(result) {
                        eval(result.data);
                        console.info('Loaded: ' + path);
                    });
                }
    
                return promise;
            }
        }
    }]);
    

    Then, define your config:

    var ng = angular.module('app', [ 'ngRoute' ]);
    
    ng.config([ '$routeProvider', '$controllerProvider', '$provide', function($routeProvider, $controllerProvider, $provide) {
        // Lazy loading
        ng.lazy = {
            controller: $controllerProvider.register,
            //directive: $compileProvider.directive,
            //filter: $filterProvider.register,
            factory: $provide.factory,
            service: $provide.service
        }
    
        $routeProvider
        .when('/', {
            templateUrl: 'view/home.html'
        })
        .when('/vendor', {
            templateUrl: 'view/vendor.html',
            resolve: {
                svc: [ 'lazyService', function(lazyService) {
                    return lazyService.loadScript('services/vendor');
                }],
                ctrl: [ 'lazyService', function(lazyService) {
                    return lazyService.loadScript('controllers/vendor');
                }]
            }
        });
    . . .
    

    On "js/services/vendor.js", create service as:

    var ng = angular.module('app');
    ng.lazy.service('vendorService', [ function() {
    . . .
    

    On "js/controllers/vendor.js", create controller as:

    var ng = angular.module('app');
    ng.lazy.controller('vendorController', [ function() {
    . . .
    

    The "resolve" property on when defines which promises should be resolved before route loads.

    0 讨论(0)
提交回复
热议问题