2013-08-24 85 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使用與選項卡/儀表板名稱名稱不同的名稱。