我试图在我的应用程序中编写通用路由,并根据路由参数动态解析视图和控制器名称。
我有以下有效的代码:
$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', }));
但是,我无法找到一种动态解析控制器名称的方法。我尝试使用此处resolve所述的方法,但是ui- router似乎处理处理的方式与angular- route不同。
resolve
有指针吗?
编辑 :我已经尝试使用,controllerProvider但是对我不起作用(例如,以下代码仅返回一个硬编码的控制器名称,以测试其是否真正起作用):
controllerProvider
controllerProvider: function () { return 'userController'; }
给我以下错误:
错误:[ng:areq]参数’userController’不是函数,未定义 http://errors.angularjs.org/1.3.3/ng/areq?p0=userController&p1=not%20aNaNunction%2C%20got%20undefined
http://errors.angularjs.org/1.3.3/ng/areq?p0=userController&p1=not%20aNaNunction%2C%20got%20undefined
这是一个到工作的plnkr的链接。
我们需要UI路由器的两个功能:
这将是我们的main.js,其中包含智能转换controllerName-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'] });
// 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"; }); });
首先,我们需要一些将参数(例如id)转换为控制器名称的方法。出于测试目的,让我们使用这个简单的实现:
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()
这最终将是我们的州定义
$stateProvider .state("default", angularAMD.route({ url: "/{id:int}", templateProvider: function($stateParams) { if ($stateParams.id === 1) { return "<div>ONE - Hallo {{title}}</div>"; } return "<div>TWO - Hallo {{title}}</div>"; }, 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; }, }));
在此工作示例中,请在此处检查
如此处所述:$ stateProvider,对于a state(name, stateConfig)我们可以使用controller和 controllerProvider 。文档摘录:
state(name, stateConfig)
controller
…
controller (可选) stringfunction
如果作为字符串传递,则控制器fn应该与新相关的作用域或已注册控制器的名称相关联。可选地,可以在此处声明ControllerA。
controller: "MyRegisteredController" controller: "MyRegisteredController as fooCtrl"} controller: function($scope, MyService) { $scope.data = MyService.getData(); }
controllerProvider (可选) 功能
返回实际控制器或字符串的可注入提供程序函数。
controllerProvider: function(MyResolveData) { if (MyResolveData.foo) return "FooCtrl" else if (MyResolveData.bar) return "BarCtrl"; else return function($scope) { $scope.baz = "Qux"; } }
resolve (可选) 对象
可选map<string, function>的依赖项,应将其注入到控制器中。 如果这些依赖项中的任何一个是promise ,则 路由器将 在实例化控制器之前 等待 它们 全部解决 。
map<string, function>
即让我们使用 controllerProvider :
…动态地解析控制器名称…
_如果您设法到达这里,也许您想使用RequireJS检查另一个类似的解决方案- 带有requirejs的angular-ui-router,延迟加载控制器