【问题标题】:dynamically loading the controller in angularjs $routeProvider在 angularjs $routeProvider 中动态加载控制器
【发布时间】:2013-08-27 16:46:23
【问题描述】:

我目前有一个内置路由的 AngularJS 应用程序,它与静态 controller 属性分配完美配合。但我真正想做的是动态分配具有不同路由的控制器:

$routeProvider
 .when("/Dashboards/:dashboardName",{
    templateUrl:function(params) {
                 return "Dashboards/" + params.dashboardName;
                //some ASP.NET MVC calls to return partial views (this part works)
        }
  })

我想做的是在这里对我的controller 属性做同样的事情,比如:

$routeProvider
 .when("/Dashboards/:dashboardName",{
       templateUrl:function(params) {
             return "Dashboards/" + params.dashboardName;
            //some ASP.NET MVC calls to return partial views (this part works)
           },
       controller: function(params) {
             return params.dashboardName+"Controller"; (this part DOESN'T work)
           }
  })

但似乎我收到一条错误消息,提示找不到 paramsProvider

那么有什么方法可以在路由配置中动态加载我的控制器函数名称吗?

【问题讨论】:

    标签: javascript angularjs angularjs-routing


    【解决方案1】:

    使用angular ui-router 可以做到这一点。

    ui-router 允许您指定“controllerProvider”来指定提供控制器的功能。所以解决方案看起来像这样:

    $stateProvider
    .state("/Dashboards/:dashboardName",{
       templateUrl:function($stateParams) {
             return "Dashboards/" + $stateParams.dashboardName;
           },
       controllerProvider: function($stateParams) {
             return $stateParams.dashboardName+"Controller";
           }
      })
    

    希望对你有帮助!

    【讨论】:

    • 啊,我重新阅读了这个问题并理解了被问到的内容(并删除了我的答案)。您的解决方案将用于动态确定控制器的名称,但仍需要从服务器动态获取和加载控制器,这似乎不是问题的一部分,但仅供未来读者参考。
    【解决方案2】:

    我解决了这个问题,没有在 $routeProvider 中指定控制器,而是将它放在 templateURL 中指定的文件中。

    $routeProvider
     .when("/Dashboards/:dashboardName",{
        templateUrl:function(params) {
                     return "Dashboards/" + params.dashboardName;
            }
      })
    

    DashboardsNAME.html

    <div class="container" ng-Controller='DashboardsNAMEController'>Food</div>
    

    这种技术仍然需要在路由实例化之前的某个时间点注册DashboardsNAMEController。我怀疑最好的方法是在 module.run() 方法中调用您自己的服务,但我在我的主控制器中这样做,因为它可以工作并且无论如何都是短控制器。

    【讨论】:

    • 这行得通,但我不明白为什么其他方式行不通。
    • @BradleyTrager 还有哪一个?
    • 问题中的控制器是在路由提供程序的函数中指定的。
    • 他正在将一个作为控制器的函数链接到路由。 routeParams 对该控制器不可用。如果他希望控制器为params.dashboardName+"Controller",他需要将该行转换为如下表达式:controller: params.dashboardName+"Controller",而不是将其包装在函数中。
    • 谢谢,我现在明白了!现在我只是想知道如何在不将其包装在函数中的情况下获取“参数”。
    【解决方案3】:

    我一直在尝试同样的事情。我发现的一种解决方案是在您的 routeProvider 中执行此操作:

     $routeProvider
        .when("/Dashboards/:dashboardName",{
            templateUrl:function(params) {
                return "Dashboards/" + params.dashboardName;
            },
            controller: 'dynamicController'
     });
    

    然后您计算要在“dynamicController”定义中加载什么“伪控制器”(因为没有更好的名称)。

    var controllers = {
        unoController: function($scope, $routeParams, $rootScope) {
            // Do whatever
        },
        dosController: function($scope, $routeParams, $rootScope) {
            // Whatever for this controller
        }
    }
    
    app.controller('dynamicController', ['$scope', '$routeParams', '$rootScope', function($scope, $routeParams, $rootScope) {
        controllers[$routeParams.dashboardName+"Controller"]($scope, $routeParams, $rootScope);
    }]);
    

    这假定 $routeParams.dashboardName 是 ["uno","dos"] 之一。

    我只用了大约 3 天的 Angular,所以对此持保留态度,但到目前为止,这种方法对于我想要完成的工作非常有效。

    【讨论】:

      【解决方案4】:

      我不知道它是否取决于 AngularJS 版本,但您可以为 controller 属性提供一个函数,该函数成为实际的控制器。将此事实与controller inheritance 结合使用,您可以获得更简洁的代码,就像您正在寻找的那样,我认为:

      $routeProvider
      .when("/Dashboards/:dashboardName",{
          templateUrl:function(params) {
              return "Dashboards/" + params.dashboardName;
          },
          controller: function($scope, $routeParams, $controller) {
              /* this creates a child controller which, 
                 if served as it is, should accomplish 
                 your goal behaving as the actual controller
                 (params.dashboardName + "Controller") */
              $controller($routeParams.dashboardName + "Controller", {$scope:$scope});
          }
      })
      

      免责声明:老实说,我不知道这种方法是否有任何缺点。不过看起来不是这样。

      【讨论】:

        【解决方案5】:

        这也是可行的,(至少对我而言)。这可能有助于未来的人们寻找答案。

        $stateProvider
            .state('foo', {
                url: '/foo/:bar',
                templateUrl: 'some-template-path.html',
                resolve : {
                    getController : function($stateParams){
                        if ($stateParams.bar === "tab1") {
        
                            return "tab1Controller"
        
                        }else if ($stateParams.bar === "tab2") {
        
                            return "tab2Controller"
        
                        }else if ($stateParams.bar === "tab3"){
        
                            return "tab3Controller"
        
                        }else if ($stateParams.bar === "tab4") {
        
                            return "tab4Controller"
        
                        }
                    }
                },
                controllerProvider: function(getController){
                    return getController;
                },
        

        不是最短的代码,但至少更容易阅读。此外,如果您想为 controller 指定与选项卡/仪表板名称不同的名称。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-07-14
          • 1970-01-01
          • 1970-01-01
          • 2019-11-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-11-07
          相关资源
          最近更新 更多