Load controller dynamically based on route group

前端 未结 4 833
夕颜
夕颜 2020-12-08 17:29

Is it possible to load a controller, it\'s js file, and a template dynamically based on a route group? Psuedo code which doesn\'t work:

$routeProvider.when(\         


        
相关标签:
4条回答
  • 2020-12-08 18:03

    I managed to solve it inspired by @calebboyd, http://ify.io/lazy-loading-in-angularjs/ and http://weblogs.asp.net/dwahlin/archive/2013/05/22/dynamically-loading-controllers-and-views-with-angularjs-and-requirejs.aspx

    Using http://dustindiaz.com/scriptjs

    app.js

    app.config(function($controllerProvider, $compileProvider, $filterProvider, $provide) {
      app.register = {
        controller: $controllerProvider.register,
        directive: $compileProvider.directive,
        filter: $filterProvider.register,
        factory: $provide.factory,
        service: $provide.service
      };
    });
    

    Then i register the "load controller by group" route.

    $routeProvider.when('/:plugin', {
    
      templateUrl: function(rd) {
        return 'plugin/' + rd.plugin + '/index.html';
      },
    
      resolve: {
        load: function($q, $route, $rootScope) {
    
          var deferred = $q.defer();
    
          var dependencies = [
            'plugin/' + $route.current.params.plugin + '/controller.js'
          ];
    
          $script(dependencies, function () {
            $rootScope.$apply(function() {
              deferred.resolve();
            });
          });
    
          return deferred.promise;
        }
      }
    });
    

    controller.js

    app.register.controller('MyPluginCtrl', function ($scope) {
      ...
    });
    

    index.html

    <div ng-controller="MyPluginCtrl">
      ...
    </div>
    
    0 讨论(0)
  • 2020-12-08 18:05

    You can use RequireJS to do this. Something like:

    $routeProvider.when('/:plugin',{
        templateUrl: 'plugins/' + plugin + '/index.html',
        controller: plugin + 'Ctrl',
        resolve: {myCtrl: function($q){
            var deferred = $q.defer();
            require('myCtrlFile',function(){
                deferred.resolve();
            });
            return deferred.promise;
        }}
    });
    

    You will also need to register the controller dynamically. By exposing your providers in the app config.

    app.config(function($controllerProvider,$compileProvider,$filterProvider,$provide){
        app.register =
            {
                controller: $controllerProvider.register,
                directive: $compileProvider.directive,
                filter: $filterProvider.register,
                factory: $provide.factory,
                service: $provide.service
            };
    });
    

    You controller file might then look like:

    define(['app'],function(app){
        app.register.controller('myCtrl',MyCtrlFunction);
    });
    

    This is just the general idea. I use a similar implementation to the one described here

    I also use ui-router. I'm not certain if behavior is the same with ngRoute.

    0 讨论(0)
  • 2020-12-08 18:21

    Here is some solution you can do for this code

    $routeProvider.when('/:plugin', function(plugin) {
      templateUrl: 'plugins/' + plugin + '/index.html',
      controller: fun,
      loadFrom:"assets/controller/myJsController"// this is our custom parameter we are passing to controller to identify the remote controller file.
    });
    

    We will create a parent function for all controller and will call all controller within this function as per defined in route configuration (in loadFrom key of route configuration).

     function fun($scope, $http, $location, $timeout, $route) {
            $timeout(function () {
            var path = $route.current.loadForm;
            $http.get("${pageContext.servletContext.contextPath}/resource/controller/" + path + ".js")
                    .then(function (rsp) {
                    eval(rsp.data);
                    });
            });
            };
    

    in assets/controller/myJsController.js file the code will be as

    (function($scope){
    //the whole code for controller will be here.
       $scope.message="working."
    
    
     })($scope)
    

    Only thing you have to remember that in parent function you have to use all dependencies.

    0 讨论(0)
  • 2020-12-08 18:21

    Simplest way with active this with less amount of code

    require.js config file.

    require.config({
        urlArgs: 'v=1.0',
        baseUrl: '/'
    });

    app.config(['$controllerProvider', '$compileProvider', '$filterProvider', '$provide','$routeProvider',function($controllerProvider, $compileProvider, $filterProvider, $provide,$routeProvider) {
      app.register = {
        controller: $controllerProvider.register,
        directive: $compileProvider.directive,
        filter: $filterProvider.register,
        factory: $provide.factory,
        service: $provide.service
      };
      // Resolver to load controller, service, directive
      var resolveController = function(dependencies) {
          return {
            load: ['$q', '$rootScope', function ($q, $rootScope) {
              var defer = $q.defer();
              require(dependencies, function () {
                  defer.resolve();
                  $rootScope.$apply();
              });
              return defer.promise;
            }]
          }
      };
      $routeProvider
        .when("/home", {
            templateUrl : "templates/home.html",
            controller: 'HomeCtrl',
            resolve: resolveController(['controller/HomeCtrl'])
        })
        .when("/ContactUs", {
            templateUrl : "templates/ContactUs.html",
            controller: 'ContactUsCtrl',
            resolve: resolveController(['controller/ContactUsCtrl'])
        })
        .when("/About", {
            templateUrl : "templates/About.html",
            controller: 'AboutCtrl',
            resolve: resolveController(['controller/AboutCtrl'])
        });
      $routeProvider.otherwise('/home');
    }]);

    Your controllers should look like this.

    define(['app'],function(app){
        app.register.controller('HomeCtrl',['$scope',function($scope){
          // Controller code goes here
        }]);
    });

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