2013-08-24 83 views
20

我目前有一个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未找到

所以有什么办法,我可以动态加载我的控制器功能名称在路由配置?

回答

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”]之一。

因为我只用了Angular 3天左右的时间,所以采用这种方法,但到目前为止,这种方法对我正试图完成的工作非常有效。

7

我通过不在$ 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()方法中调用你自己的服务,但是我在我的主控制器中执行它,因为它工作并且总是很短的控制器。

+0

这可行,但我不明白为什么其他方式不起作用。 –

+0

@BradleyTrager哪一个? –

+0

控制器在路由提供者的函数中指定的问题。 –

10

这是可以使用angular ui-router

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

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

我希望它有帮助!

+0

啊,我重读了这个问题,并理解了被问到的内容(并删除了我的答案)。您的解决方案可以动态确定控制器的名称,但控制器仍然需要从服务器动态获取并加载,这似乎不属于问题的一部分,但是对于未来的读者来说,它只是一个参考。 – TheSharpieOne

3

我不知道它是否依赖于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}); 
    } 
}) 

声明:我真的不知道,如果这种方式有什么缺点。虽然看起来不是这样。

+0

这似乎与'resolve's不兼容。 – N13

0

这里也是可行的,(至少对我而言)。这可以帮助未来的人寻找答案。

$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使用与选项卡/仪表板名称名称不同的名称。