2013-08-24 12 views
20

Attualmente ho un'app AngularJS con routing integrato e funziona perfettamente con assegnazioni di proprietà statiche controller. ma quello che voglio fare è quello di assegnare dinamicamente controller con percorsi diversi:

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

Quello che vorrei fare è quello di fare la stessa cosa di mia proprietà controller qui, come:

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

ma, a quanto pare, viene visualizzato un messaggio di errore che indica

quindi è possibile caricare dinamicamente il nome della funzione del controller nella configurazione del percorso?

risposta

3

Ho provato questa stessa cosa. Una soluzione che ho trovato è di fare questo all'interno del vostro routeProvider:

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

E poi si fa il calcolo di ciò che "pseudo-Controller" (per mancanza di un nome migliore) per caricare all'interno della "dynamicController" definizione.

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

Questo presuppone che $ routeParams.dashboardName è uno dei [ "UNO", "dos"].

Prendere questo con un granello di sale come ho avuto solo circa 3 giorni con Angular, ma finora questo approccio ha funzionato benissimo per quello che sto cercando di realizzare.

7

Ho risolto questo problema non specificando il controller in $ routeProvider ma inserendolo nel file specificato in templateURL.

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

In DashboardsNAME.html

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

Questa tecnica richiede ancora che ad un certo punto prima che il percorso viene istanziato aver registrato DashboardsNAMEController. Sospetto che il modo migliore per farlo sia nel metodo module.run() con la chiamata al proprio servizio ma lo faccio nel mio controller principale perché funziona e comunque è un controller corto.

+0

Questo funziona, ma non capisco perché l'altro modo non funziona. –

+0

@BradleyTrager Quale altro? –

+0

Quello nella domanda in cui il controller è specificato in una funzione sul provider del percorso. –

10

È possibile utilizzare angular ui-router.

L'ui-router consente di specificare un "controllerProvider" per specificare una funzione per fornire un controller. Quindi la soluzione sarebbe simile a questa:

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

Spero che sia d'aiuto!

+0

ah, ho riletto la domanda e capito cosa è stato chiesto (e rimosso la mia risposta). La soluzione funzionerà per determinare dinamicamente il nome del controller, ma il controller dovrà comunque essere scaricato e caricato dal server in modo dinamico, il che non sembra essere parte della domanda, ma una FYI per i futuri lettori. – TheSharpieOne

3

Non so se dipende dalla versione di AngularJS ma è possibile fornire una funzione alla proprietà controller, la funzione diventa il controller corrente. Usando questo fatto in collaborazione con controller inheritance è possibile ottenere un codice più condensata come quello che stavate cercando, penso:

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

Disclaimer: sinceramente non so se questo approccio ha degli svantaggi. Non sembra così però.

+0

Questo non sembra funzionare bene con 'resolve's. – N13

0

Ecco qualcosa che funziona anche, (almeno per me).Questo può aiutare le persone future alla ricerca di una risposta.

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

Non è il codice più breve ma almeno è più facile da leggere. Inoltre, se si desidera assegnare a controller un nome diverso dal nome della scheda/dashboardName.

Problemi correlati