欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  web前端

AngularJS如何实现动态加载Controller

程序员文章站 2022-05-23 17:38:47
...
本篇文章给大家分享的内容是AngularJS如何实现动态加载Controller,有着一定的参考价值,有需要的朋友可以参考一下

我们把实现动态加载Controller方法封装到一个通用的模块里面,并命名这个模块为ngCommon

(function (angular) {'use strict';
    var CommonApp = angular.module('ngCommon');
    ...
    })(angular);

接下来我们实现一个动态加载js的方法$require

/* 记录已加载的js */
var loaded = {};
/* 检测是否加载 */
var checkLoaded = function (url) {
    return !url || !angular.isString(url) || loaded[url];};
    
    CommonApp.factory('$require', ['$document', '$q', '$rootScope', function ($document, $q, $rootScope) {
    return function (url) {
        var script = null;
        var onload = null;
        var doc = $document[0];
        var body = doc.body;
        var deferred = $q.defer();
        if (checkLoaded(url)) {
            deferred.resolve();
        } else {
            script = doc.createElement('script');
            onload = function (info) {
                if (info === 1) {
                    deferred.reject();
                } else {
                    loaded[url] = 1;
                    /* AngularJS < 1.2.x 请使用$timeout */
                    $rootScope.$evalAsync(function () {
                        deferred.resolve();
                    });
                }
                script.onload = script.onerror = null;
                body.removeChild(script);
                script = null;
            };
            script.onload = onload;
            script.onerror = function () {
                onload(1);
            };
            script.async = true;
            script.src = url;
            body.appendChild(script);
        }
        return deferred.promise;
    };}]);

然后重点来了,通过$routeProvider routeresolve功能来实现动态加载Controller。

CommonApp.provider('$routeResolver', function () {
    this.$get = function () {
        return this;
    };
    this.route = function (routeCnf) {
        var controller = routeCnf.controller;
        var controllerUrl = routeCnf.controllerUrl;
        if (controllerUrl) {
            routeCnf.reloadOnSearch = routeCnf.reloadOnSearch || false;
            routeCnf.resolve = {
                load: ['$route', '$require', 'ControllerChecker',
                    function ($route, $require, ControllerChecker) {
                        var controllerName = angular.isFunction(controller) ? controller($route.current.params) : controller;
                        var url = angular.isFunction(controllerUrl) ? controllerUrl($route.current.params) : controllerUrl;
                        if (checkLoaded(url) || (controllerName && ControllerChecker.exists(controllerName))) {
                            loaded[url] = true;
                            return;
                        }
                        return $require(url);
                }]
            };
        }
        return routeCnf;
    };})

看上面的代码中还注入了一个叫ControllerChecker的,这个是用来检测当前Controller是否已经注册了,如果未注册,那么我们就加载相关js注册新的Controller。代码如下:

CommonApp.service('ControllerChecker', ['$controller', function ($controller) {
    return {
        exists: function (controllerName) {
            if (angular.isFunction(window[controllerName])) {
                return true;
            }
            try {
                $controller(controllerName, {}, true);
                return true;
            } catch (e) {
                return false;
            }
        }
    };}]);

最后我们来添加一个注动态册的方法。

CommonApp.setupRegister = function (module) {
    module.config([
        '$controllerProvider',
        '$compileProvider',
        '$filterProvider',
        '$provide',
        function ($controllerProvider, $compileProvider, $filterProvider, $provide) {
            module.register = {
                controller: $controllerProvider.register,
                directive: $compileProvider.directive,
                filter: $filterProvider.register,
                factory: $provide.factory,
                service: $provide.service,
                value: $provide.value,
                constant: $provide.constant            };
        }
    ]);};

到此已经基本完成了,如何使用呢?

var DemoApp = angular.module('DemoApp',['ngRoute','ngCommon']);
/* 调用动态注册方法,为当前模块添加动态注册方法 */
angular.module('ngCommon').setupRegister(DemoApp);
DemoApp.config(['$routeProvider', '$routeResolverProvider', function ($routeProvider, $routeResolverProvider) {
    var route = $routeResolverProvider.route;
    $routeProvider.when('/index', route({
        templateUrl: './view/index.html'),
        controller: 'IndexController', /* 在此申明了controller就不需要再html里面申明ng-controller了 */
        controllerUrl: './controller/index.js')
    }))
    .otherwise('/index');/* ./controller/index.js */DemoApp.register.controller('IndexController', ['$scope', '$require', function($scope, $require) {
    ...
    /* 动态加载某个js文件 */
    $require(url).then(function () {
        ...
    });}]);

以上就是AngularJS如何实现动态加载Controller的详细内容,更多请关注其它相关文章!