AngularAMD + roteador-ui + nome do controlador dynamic?

Eu estou tentando escrever uma rota generalizada em meu aplicativo e resolver os nomes de exibição e controlador na mosca com base nos parâmetros de rota.

Eu tenho o seguinte código que funciona:

$stateProvider.state('default', angularAMD.route({ url: '/:module/:action?id', templateUrl: function (params) { var module = params.module; var action = module + params.action.charAt(0).toUpperCase() + params.action.substr(1); return 'app/views/' + module + '/' + action + 'View.html'; }, controller: 'userController', })); 

No entanto, não consigo descobrir uma maneira de resolver dinamicamente o nome do controlador. Eu tentei usar resolve como descrito aqui , mas o ui-router parece lidar com a resolução de maneira diferente da rota angular.

Alguma ponteira?

Edição : Eu já tentei usar controllerProvider mas não funciona para mim (por exemplo, o código a seguir apenas retorna um nome de controlador codificado para testar se ele realmente funciona):

 controllerProvider: function () { return 'userController'; } 

Me dá o seguinte erro:

Erro: [ng: areq] Argumento ‘userController’ não é uma function, tem undefined http://errors.angularjs.org/1.3.3/ng/areq?p0=userController&p1=not%20aNaNunction%2C%20got%20undefined

Este é um link para o plunker de trabalho .

solução

Precisamos de dois resources do roteador de interface do usuário:

  • resolve (para carregar as partes que faltam do código js)
  • controllerProvider (consulte as referências da documentação abaixo)

angularAMD – main.js definição

Este seria o nosso main.js, que contém o controlador de conversão inteligenteName – controllerPath:

 require.config({ //baseUrl: "js/scripts", baseUrl: "", // alias libraries paths paths: { "angular": "angular", "ui-router": "angular-ui-router", "angularAMD": "angularAMD", "DefaultCtrl": "Controller_Default", "OtherCtrl": "Controller_Other", }, shim: { "angularAMD": ["angular"], "ui-router": ["angular"], }, deps: ['app'] }); 

controladores:

 // Controller_Default.js define(['app'], function (app) { app.controller('DefaultCtrl', function ($scope) { $scope.title = "from default"; }); }); // Controller_Other.js define(['app'], function (app) { app.controller('OtherCtrl', function ($scope) { $scope.title = "from other"; }); }); 

app.js

Em primeiro lugar, precisaríamos de algum método para converter o parâmetro (por exemplo, id) em nome do controlador. Para os nossos testes, vamos usar esta implementação ingênua:

 var controllerNameByParams = function($stateParams) { // naive example of dynamic controller name mining // from incoming state params var controller = "OtherCtrl"; if ($stateParams.id === 1) { controller = "DefaultCtrl"; } return controller; } 

.state()

E isso seria finalmente a nossa definição de estado

 $stateProvider .state("default", angularAMD.route({ url: "/{id:int}", templateProvider: function($stateParams) { if ($stateParams.id === 1) { return "
ONE - Hallo {{title}}
"; } return "
TWO - Hallo {{title}}
"; }, resolve: { loadController: ['$q', '$stateParams', function ($q, $stateParams) { // get the controller name === here as a path to Controller_Name.js // which is set in main.js path {} var controllerName = controllerNameByParams($stateParams); var deferred = $q.defer(); require([controllerName], function () { deferred.resolve(); }); return deferred.promise; }] }, controllerProvider: function ($stateParams) { // get the controller name === here as a dynamic controller Name var controllerName = controllerNameByParams($stateParams); return controllerName; }, }));

Confira aqui, neste exemplo de trabalho

documentação

Como documentado aqui: $ stateProvider , para um state(name, stateConfig) podemos usar controller e controllerProvider . Alguns extrair da documentação:

controllerProvider

Cadeia de caracteres do controller (opcional)

O controlador fn que deve ser associado ao escopo recém-relacionado ou ao nome de um controlador registrado, se passado como uma string. Opcionalmente, os ControllerAs podem ser declarados aqui.

 controller: "MyRegisteredController" controller: "MyRegisteredController as fooCtrl"} controller: function($scope, MyService) { $scope.data = MyService.getData(); } 

controllerProvider (opcional)

Função de provedor injetável que retorna o controlador ou string real.

 controllerProvider: function(MyResolveData) { if (MyResolveData.foo) return "FooCtrl" else if (MyResolveData.bar) return "BarCtrl"; else return function($scope) { $scope.baz = "Qux"; } } 

resolver

resolve object (opcional)

Um map opcional map de dependencies que deve ser injetado no controlador. Se alguma dessas dependencies for promissora , o roteador esperará que TODOS sejam resolvidos antes que o controlador seja instanciado …

Ou seja, vamos usar o controllerProvider :

… para resolver o nome do controlador dinamicamente …

No caso, que você conseguiu chegar aqui, talvez você gostaria de verificar outra solução semelhante com RequireJS – angular-ui-roteador com requirejs, carregamento lento do controlador

Intereting Posts