在$ routeProvider中使用resolve会导致'Unknown provider ...'

时间:2013-12-18 14:50:54

标签: angularjs controller angularjs-routing route-provider

我正在尝试执行异步http请求以在我的应用加载之前加载一些数据,因此我在$ routeProvider中使用了一个解析,这是我的MainController中的http请求。出于某种原因,我一直得到错误:[$ injector:unpr]未知提供者:appDataProvider< - appData 其中appData是我做http请求的地方。我正在使用AngularJS v 1.2.5。

以下是我尝试的代码和两个方法,它们都给出了同样的错误:

方法#1

MainController.js

var MainController = ['$scope','$location','appData',
    function($scope, $location, appData){
       console.log(appData.data);
    }
];

MainController.loadData = {
    appData: function($http, $location, MainFactory){
        var aid = MainFactory.extractAid($location);
        return $http({method: 'GET', url: URL_CONST + aid});
    }
};

app.js

var app = angular.module('HAY', ['ngRoute']);

app.config(function($routeProvider) {
  $routeProvider
    .when('/', {
      redirectTo: '/pages/alerts'
    })
    .when('/pages/:pageName', {
        templateUrl: function(params) {
            return 'views/pages/' + params.pageName + '.html';
        },
        controller: MainController,
        resolve: MainController.loadData
    })
    .otherwise({
        redirectTo: '/pages/alerts'
    });
});

我尝试更改名称,以防它是一个冲突的系统保留关键字,但没有运气。出于某种原因, appData 永远不会被识别

方法#2 我也尝试过改变它:

app.js

var app = angular.module('HEY', ['ngRoute']);

app.config(function($routeProvider) {
  $routeProvider
    .when('/', {
      redirectTo: '/pages/alerts'
    })
    .when('/pages/:pageName', {
        templateUrl: function(params) {
            return 'views/pages/' + params.pageName + '.html';
        },
        controller: MainController,
        resolve: {
                appData: ['$http', '$location','MainFactory', function($http, $location, MainFactory) {
                    var aid = MainFactory.extractAid($location);
                    return $http({method: 'GET', url: URL_CONST + aid});
                }]
        }
    })
    .otherwise({
        redirectTo: '/pages/alerts'
    });
});

MainController.js

var MainController = ['$scope','$location','appData',
    function($scope, $location, appData){
        console.log(resolvedData);
    }
];

然而,结果完全一样。这与angular 1.2.5有关吗?

以下是其他人的工作版本

http://mhevery.github.io/angular-phonecat/app/#/phones

以下是代码:

function PhoneListCtrl($scope, phones) {
  $scope.phones = phones;
  $scope.orderProp = 'age';
}

PhoneListCtrl.resolve = {
  phones: function(Phone) {
    return Phone.query();
  },
  delay: function($q, $defer) {
    var delay = $q.defer();
    $defer(delay.resolve, 1000);
    return delay.promise;
  }
}

angular.module('phonecat', ['phonecatFilters', 'phonecatServices', 'phonecatDirectives']).
  config(['$routeProvider', function($routeProvider) {
    $routeProvider.
        when('/phones', {templateUrl: 'partials/phone-list.html', controller: PhoneListCtrl, resolve: PhoneListCtrl.resolve}).
        otherwise({redirectTo: '/phones'});
  }]);

3 个答案:

答案 0 :(得分:2)

以下是我正在使用的应用程序中使用的代码示例,不确定它会有多大帮助,因为它与您已经拥有的代码没有多大差别。

<强>路由

.when('/view/proposal/:id',{
    controller : 'viewProposalCtrl',
    templateURL : 'tmpls/get/proposal/view',
    resolve : viewProposalCtrl.resolveViewProposal
})

<强>控制器

var viewProposalCtrl = angular.module('proposal.controllers')
    .controller('viewProposalCtrl',['$scope','contacts','details','rationale',
        function($scope,contacts,details,rationale){
            $scope.contacts = contacts;
            $scope.details = details;
            $scope.rationale = rationale;

            // [ REST OF CONTROLLER CODE ]
        });


// proposalSrv is a factory service

viewProposalCtrl.resolveViewProposal = {
    contacts : ['$route','proposalSrv',function($route,proposalSrv){
        return proposalSrv.get('Contacts',$route.current.params.id)
           .then(function(data){
               return data.data.contacts;
           },function(){
               return [];
           });
    }],
    details : ['$route','proposalSrv',function($route,proposalSrv){
        return proposalSrv.get('Details',$route.current.params.id)
            .then(function(data){
                return data.data.details;
            },function(){
                return {};
            });
    }],
    rationale : ['$route','proposalSrv',function($route,proposalSrv){
        return proposalSrv.get('Rationale',$route.current.params.id)
            .then(function(data){
                return data.data.rationale;
            },function(){
                return {};
            ]
    }]
};

现在我考虑一下,当我开发我的应用程序时,我确实遇到了问题,并且不确定为什么当我命名我的解析函数时“解决”。这给了我一个问题:

.when('/path',{
     // stuff here
     resolve : myCtrlr.resolve
})

但这没有:

.when('/path',{
     //stuff here
     resolve : myCtrlr.myResolveFn
})

另一种可能性

我能想到的另一件事是,您从$http调用中返回承诺,然后尝试使用appData.data尝试使用{{ 1}}函数或其他函数之一(.then.success)来从promise中检索信息。

答案 1 :(得分:1)

由于之前使用的是不同版本的AngularJS,问题是 NOT

以下是使用我上面代码的修补程序。

在app.js中,你需要将控制器声明为 controller:'MainController'而不是控制器:MainController,即使你有var MainController = app.controller('MainController',.. ..)。

第二个也是最重要的是,在我的index.html中,我声明我的控制器已经如此:

的index.html

body ng-app =“HEY”controller =“MainController”/ body

这导致整个未知提供程序错误显然有角度不会告诉您已经声明了您正在使用的控制器来解决它并且这将导致与解决方案无关的奇怪错误。 / p>

我希望这可以帮助那些可能遇到同样问题的人。

答案 2 :(得分:0)

我在有角度的1x文档中注意到的一件事是你没有将解析的参数指定为注释依赖

所以这个:

.when('/somewhere', {
  template: '<some-component></some-component>',
  resolve: {
    resolvedFromRouter: () => someService.fetch()
  }
})

export default [
  '$scope',
  'someService',
  'resolvedFromRouter'
  Controller
]

function Controller($scope, someService, resolvedFromRouter) {
  // <= unknown provider "resolvedFromRouter"
}

错了。您没有在docs:

中将已解析的参数指定为依赖项
  

为了更轻松地从模板访问已解析的依赖项,解析映射将在路径范围内提供,在$ resolve(默认情况下)或resolveAs属性指定的自定义名称下(见下文)。当使用组件作为路径模板时,这可能特别有用。

所以只需这样做:

.when('/somewhere', {
  template: '<some-component></some-component>',
  resolve: {
    resolvedFromRouter: () => someService.fetch()
  }
})

export default [
  '$scope',
  'someService',
  Controller
]

function Controller($scope, someService) {
  $scope.$resolve.resolvedFromRouter; // <= injected here
}