2013-08-24 17 views
20

Aktualnie mam aplikację AngularJS z wbudowanym routingiem i działa ona doskonale ze statycznymi zadaniami controller. ale to, co naprawdę chcesz robić to dynamicznie przypisywać kontrolerów z różnymi drogami:

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

Co chciałbym zrobić, to zrobić to samo o mojej controller nieruchomości tutaj, jak:

$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) 
      } 
    }) 

ale jak wydaje się, otrzymuję komunikat o błędzie mówiąc, że paramsProvider nie zostanie znaleziony

, czy istnieje sposób dynamicznego ładowania nazwy funkcji kontrolera w konfiguracji trasy?

Odpowiedz

3

Próbowałem tego samego. Jednym rozwiązaniem znalazłem jest to zrobić wewnątrz routeProvider:

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

A następnie wykonać obliczenia dla co „pseudo-kontrolera” (z braku lepszej nazwy) do załadowania wewnątrz „dynamicController” definicja.

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); 
}]); 

Zakłada się, że $ routeParams.dashboardName jest jednym z ["uno", "dos"].

Weź to z przymrużeniem oka, ponieważ miałem tylko około 3 dni z Angularem, ale jak dotąd to podejście zadziałało doskonale dla tego, co próbuję osiągnąć.

7

Rozwiązałem ten problem, nie określając kontrolera w $ routeProvider, lecz umieszczając go w pliku określonym w templateURL.

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

W DashboardsNAME.html

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

Technika ta wymaga jeszcze, że w pewnym momencie przed trasie jest tworzony zarejestrowaniu DashboardsNAMEController. Podejrzewam, że najlepszym miejscem na to jest metoda module.run() z wywołaniem do własnej usługi, ale robię to w moim głównym kontrolerze, ponieważ działa i jest i tak krótkim kontrolerem.

+0

To działa, ale nie rozumiem, dlaczego ta druga metoda nie działa. –

+0

@BradleyTrager Który inny? –

+0

Ten w pytaniu, gdzie kontroler jest określony w funkcji na dostawcy trasy. –

10

Można to zrobić za pomocą angular ui-router.

Ui-router pozwala określić "kontrolerProvider", aby określić funkcję dla zapewnienia kontrolera. Rozwiązanie powinno wyglądać następująco:

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

Mam nadzieję, że pomoże!

+0

ah, ponownie przeczytałem pytanie i zrozumiałem, o co pytano (i usunąłem odpowiedź). Twoje rozwiązanie będzie działać w celu dynamicznego określania nazwy kontrolera, ale kontroler wciąż będzie musiał być pobierany i ładowany z serwera dynamicznie, co nie wydaje się być częścią pytania, ale FYI dla przyszłych czytelników. – TheSharpieOne

3

Nie wiem, czy to zależy od wersji AngularJS, ale można podać funkcję do właściwości controller, funkcja staje się rzeczywistym kontrolerem. Stosując ten fakt w połączeniu z controller inheritance można uzyskać bardziej skondensowane kod podobny do tego, czego szukasz, myślę:

$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}); 
    } 
}) 

Zastrzeżenie: Szczerze mówiąc, nie wiem, czy to podejście ma żadnych wad. Nie wygląda jednak tak.

+0

Wydaje się, że nie działa to dobrze w 'rozwiązaniach'. – N13

0

Oto coś, co działa również (przynajmniej dla mnie).Może to pomóc przyszłym osobom szukającym odpowiedzi.

$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; 
     }, 

Nie jest to najkrótszy kod, ale przynajmniej łatwiejszy do odczytania. Także jeśli chcesz nadać controller inną nazwę z nazwy karty/dashboardName.

Powiązane problemy