refactor large AngularJS module config into separate files

前端 未结 3 1525
傲寒
傲寒 2020-12-15 19:53

Problem: Large config()

The config of my AngularJS app is growing quite large. How would you refactor the following into separate files?



        
相关标签:
3条回答
  • 2020-12-15 20:36

    I would look at browserify

    It allows you to use markup to require modules in your javascript.

    This would allow you to break up your config into multiple files while keeping them together (see example).

    browserify compiles your javascript into a single bundle.js by recursively tracing the requires from your main javascript file.

    You then only need to include <script src="bundle.js"></script> on your index.html

    Short Example

    Javascript

    'use strict';
    
    require('angular/angular');
    require('angular-ui/ui-router');
    
    var app = angular.module('vw', ['ui.router', 'myApp.feature1', 'myApp.feature2'])
                     .config(require('./config/route'))
                     .config(require('./config/httpProvider'));
    
    angular.bootstrap(document, ['myApp']);
    

    File Structure

    • myApp
      • config
        • route.js
        • httpProvider.js
      • myApp.js
      • index.html
    0 讨论(0)
  • 2020-12-15 20:55

    You can use .constant as a dependency in a .config, so you could use the config declaration as a manual composition root. For example:

    angular.module('myApp')
        .config(function($urlRouterProvider, $stateProvider, $httpProvider,
                         routerConfig, httpInterceptorConfig) {
            routerConfig($urlRouterProvider, $stateProvider);
            httpInterceptorConfig($httpProvider);
        });
    
    // routerConfig.js
    angular.module('myApp')
        .constant('routerConfig', function($urlRouterProvider, $stateProvider) {
            ...
        });
    
    // httpInterceptorConfig.js
    angular.module('myApp')
        .constant('httpInterceptorConfig', function($httpProvider) {          
            ...
        });
    

    Drawbacks to this approach are that you have to inject all of your config dependencies into the root config function, then manually inject them into your constant config functions. If you have a lot of different config functions, this could get messy. It can also look kind of like your config functions are having dependencies injected by Angular, but in fact you are doing it manually. You would need to make sure you remember to do the manual wiring every time you add a new config function.

    My preferred approach is just to have a folder called "config" containing exclusively config calls.

    0 讨论(0)
  • 2020-12-15 20:59

    I just did this recently with a provider.

       angular.module('EventView')
    .provider('routing', ['$stateProvider', '$urlRouterProvider',
        function($stateProvider, $urlRouterProvider) {
            this.init = function() {
                // For any unmatched url, redirect to /home
                $urlRouterProvider.otherwise('/home');
    
                // Now set up the states
                $stateProvider
                    .state('login', {
                        url: '/account/login?{redirectUrl}',
                        controller: 'loginCtrl',
                        templateUrl: 'partials/account/login/login.tpl.html'
                    })
            }
    
            // has to be here
            this.$get = function() {
                return {};
            };
        }
    ]);
    

    In the config you can just call the function.

    angular.module('EventView').config(['routingProvider', function (routingProvider) {
            routingProvider.init();         
        }
    ]);
    

    There are two gotachas, first that the name of the provider adds provider to it when you reference from the config and the second is that you have to implement the $get and return a function.

    Good luck!

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