我有一个,ui-router StateProvider并且需要根据外部数据在控制器和视图之间进行选择,因此我使用TemplateProvider和ControllerProvider。
ui-router
StateProvider
TemplateProvider
ControllerProvider
如果我只有TemplateProvider它,一切都很好,但是当我添加时,ControllerProvider会出现此错误:
Error: [ng:areq] Argument 'fn' is not a function, got Object http://errors.angularjs.org/1.3.1/ng/areq?p0=fn&p1=not%20aNaNunction%2C%20got%Object at REGEX_STRING_REGEXP (http://localhost:48510/Scripts/Vendor/Angular/1-angular.js:80:12) at assertArg (http://localhost:48510/Scripts/Vendor/Angular/1-angular.js:1577:11) at assertArgFn (http://localhost:48510/Scripts/Vendor/Angular/1-angular.js:1587:3) at annotate (http://localhost:48510/Scripts/Vendor/Angular/1-angular.js:3417:5) at invoke (http://localhost:48510/Scripts/Vendor/Angular/1-angular.js:4096:21) at Object.instantiate (http://localhost:48510/Scripts/Vendor/Angular/1-angular.js:4129:23) at http://localhost:48510/Scripts/Vendor/Angular/1-angular.js:8320:28 at compile (http://localhost:48510/Scripts/Vendor/AngularUIRouter/angular-ui-router.js:3897:28) at invokeLinkFn (http://localhost:48510/Scripts/Vendor/Angular/1-angular.js:8081:9) at nodeLinkFn (http://localhost:48510/Scripts/Vendor/Angular/1-angular.js:7593:11)
undefined serviceName可能看起来有些像(它说有对象,但看起来像,undefined但是我不太擅长调试AngularJs)
undefined
serviceName
AngularJs
这是我的代码:
.state('abstractParent.childState', { url: '/childState', controllerProvider: ['myService', function (myService) { return myService .isSpecificMember() .then(function (result) { //this returns a promise of a bool. if (result.data) { return 'SpecificController'; } else { return 'GeneralController'; } }) }], templateProvider: ['myService', '$templateFactory', function (myService, $templateFactory) { return myService.isSpecificMember().then(function(result) { if(result.data) { return $templateFactory.fromUrl('SpecificView'); } else { return $templateFactory.fromUrl('GenericView'); } }) }], resolve: { thing: ['thingService', function (thingService) { //this is only used in one of the controllers. return thingService.getThing(); }] }})
编辑
基于RadimKöhlers答案的更改
.state('abstractParent.childState', { url: '/childState', resolve: { controllerName: ['myService', function (myService) { return myService.isSpecificMember().then(function (result) { //this returns a promise of a bool. if (result.data) { return 'SpecificController'; } else { return 'GeneralController'; } }) }], thing: ['thingService', function (thingService) { //this is only used in one of the controllers. return thingService.getThing(); }] }, controllerProvider: ['controllerName', function (controllerName) { return controllerName; }], templateProvider: ['myService', '$templateFactory', function (myService, $templateFactory) { return myService.isSpecificMember().then(function(result) { if(result.data) { return $templateFactory.fromUrl('SpecificView'); } else { return $templateFactory.fromUrl('GenericView'); } }) }] })
新错误:
Error: [$injector:unpr] Unknown provider: controllerNameProvider <- controllerName http://errors.angularjs.org/1.3.1/$injector/unpr?p0=controllerNameProvider%20%3C-%20controllerName at REGEX_STRING_REGEXP (1-angular.js:80) at 1-angular.js:3930 at Object.getService [as get] (1-angular.js:4077) at 1-angular.js:3935 at getService (1-angular.js:4077) at Object.invoke (1-angular.js:4109) at angular-ui-router.js:3465 at processQueue (1-angular.js:12901) at 1-angular.js:12917 at Scope.$get.Scope.$eval (1-angular.js:14110)
解
这至少需要版本0.2.14的angular-ui-router.js
0.2.14
angular-ui-router.js
问题是,这controllerProvider只是必须返回 对象 代表controller或string (它的名字)
controllerProvider
controller
string
http://angular-ui.github.io/ui- router/site/#/api/ui.router.state。$ stateProvider
stateConfig.controllerProvider (可选) 功能 返回实际 控制器 或 字符串的可 注入提供程序函数。
stateConfig.controllerProvider (可选) 功能
stateConfig.controllerProvider
返回实际 控制器 或 字符串的可 注入提供程序函数。
因此,我们无法兑现承诺…
但是有一个解决方案:
有一个可行的例子
我们可以使用内置的功能 解析 -通过使用异步功能来完成异步工作,并使其controllerProvider成为英雄-
resolve: { controllerName: ['$stateParams', '$timeout','$q', function ($stateParams, $timeout, $q) { var deferred = $q.defer(); $timeout(function(){ deferred.resolve('MyLazyRevealedCtrl'); },250); return deferred.promise; }], }, controllerProvider:['controllerName', function (controllerName) { return controllerName; }],
我们看到的是仅带有计时器的简化示例(扮演async的角色 .then() )。等待一会儿,然后返回解析的控制器名称。
.then()
在 controllerProvider 随后 (一旦全部解决) 只需要这一结果,并返回一个字符串。
在这里检查