Использование разрешения в $routeProvider вызывает «Неизвестный поставщик»

Я пытаюсь выполнить асинхронный http-запрос для загрузки некоторых данных до загрузки моего приложения, поэтому я использую разрешение в $routeProvider, которое является http-запросом в моем MainController. По какой-то причине я продолжаю получать сообщение Ошибка: [$injector:unpr] Неизвестный поставщик: appDataProvider ‹- appData, где appData — это то место, где я делаю свой HTTP-запрос. Я использую AngularJS версии 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'});
  }]);

person Georgi Angelov    schedule 18.12.2013    source источник
comment
appData не является модулем. Вам не нужно вводить его.   -  person zs2020    schedule 18.12.2013
comment
хм совсем наоборот. Мне нужно его ввести, иначе не распознается. Я использовал его раньше.   -  person Georgi Angelov    schedule 18.12.2013
comment
Вы можете внедрить MainFactory, но не функцию.   -  person zs2020    schedule 18.12.2013
comment
Я не согласен. Вы можете, конечно, ввести его. Взгляните на пример, который я предоставил сразу после моего кода.   -  person Georgi Angelov    schedule 18.12.2013
comment
Я согласен, я ввожу разрешенные параметры в свой контроллер, все работает нормально.   -  person m.e.conroy    schedule 18.12.2013
comment
@GeorgiAngelov Я использую Angular 1.1.5 в приложении, над которым работаю.   -  person m.e.conroy    schedule 18.12.2013
comment
@GeorgiAngelov вызов $http возвращает то, что вы ожидали? Попробуйте использовать инструменты разработчика Chrome и посмотрите на вкладку «Сеть» и посмотрите, что возвращает этот вызов. Может быть, что-то там идет не так и искажает ожидаемое значение промиса.   -  person m.e.conroy    schedule 18.12.2013
comment
@m.e.conroy, решение было просто нелепым. Пожалуйста, посмотрите решение, которое я разместил. Я надеюсь, что это поможет кому-то еще, у кого может быть такая же проблема.   -  person Georgi Angelov    schedule 18.12.2013
comment
@GeorgiAngelov Второе, на что вы указываете, помогло мне решить проблему. Я совершенно забыл, что я также установил ng-controller на основной корпус :) Спасибо.   -  person Jack Vo    schedule 24.10.2014
comment
@JackVo, я рад, что это помогло! Кажется, что-то, что не должно вызывать столько проблем;)   -  person Georgi Angelov    schedule 24.10.2014
comment
Пункт решения 2 помог мне использовать angularjs v1.3.2   -  person Sam Vloeberghs    schedule 14.11.2014
comment
@SamVloeberghs, я очень рад, что это помогло   -  person Georgi Angelov    schedule 15.11.2014
comment
Вы должны ответить на свой вопрос с приведенными выше выводами / деталями! Для меня это оказалась ссылка на контроллер в файле ng-include. Точно так же, как вы упомянули выше, обращение к контроллеру вызывает ошибку Неизвестный поставщик, по-видимому, также для частичных/включенных. Решение состояло в том, чтобы дать включению собственный контроллер, тогда все работает.   -  person davidkonrad    schedule 21.02.2018
comment
@davidkonrad, я рад, что это помогло! Я только что опубликовал свой собственный ответ, поэтому надеюсь, что это немного понятнее для людей, рассматривающих этот вопрос. Спасибо!   -  person Georgi Angelov    schedule 25.02.2018


Ответы (3)


Вот пример кода, который я использовал в приложении, над которым я работаю, не уверен, что он сильно поможет, потому что он не сильно отличается от того, как он у вас уже есть.

Маршрутизация

.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 Попробуйте использовать функцию .then или одну из других функций (.success,.error) для получения информации из обещания.

person m.e.conroy    schedule 18.12.2013
comment
Спасибо за этот пример. Моя проблема в том, что я даже не могу внедрить функции, чтобы фактически использовать then() или .success,.error) . Я до сих пор не могу понять, почему. Я начинаю думать, что angularjs 1.2.5 делает что-то не так, как раньше. - person Georgi Angelov; 18.12.2013
comment
Это возможно, многое изменилось с версии 1.1.5. Возможно, вам не хватает модуля или чего-то еще, возможно, что-то было исключено из основного кода, например ngRoute. - person m.e.conroy; 18.12.2013
comment
Я только что выложил решение этой проблемы. - person Georgi Angelov; 18.12.2013
comment
У этого дизайна есть проблема, если вы сделаете: var controller = angular.module().controller(), с двумя разными контроллерами обе переменные будут привязаны к одному и тому же объекту. Следовательно, у вас не может быть двух контроллеров с одинаковыми именами методов resolveXX(), иначе на каждой странице будет выполняться только последний из них. - person El pocho la pantera; 16.12.2016
comment
У меня никогда не было проблем с тем, как я описал, у меня есть крупномасштабные приложения, написанные как таковые, которые работают просто отлично. - person m.e.conroy; 16.12.2016

Проблема была НЕ из-за того, что ранее использовалась другая версия AngularJS.

Вот исправления с использованием кода, который у меня есть выше.

В app.js вам нужно объявить контроллер как controller: 'MainController', а НЕ как контроллер: MainController, даже если у вас есть var MainController = app.controller('MainController', ....) .

Вторая и самая важная вещь заключалась в том, что в моем index.html я уже объявил свой контроллер так:

index.html

body ng-app="HEY" контроллер="MainController" /тело

Это вызывало всю ошибку неизвестного провайдера. По-видимому, angular не скажет вам, что вы уже объявили контроллер, который используете для его разрешения, и что это вызовет странную ошибку, которая не имеет ничего общего с разрешением.

Я надеюсь, что это поможет кому-то, у кого может быть такая же проблема.

person Georgi Angelov    schedule 25.02.2018

Одна вещь, которую я заметил в документах angular 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"
}

неправильно. Вы не указываете разрешенный параметр как зависимость в документах:

Для упрощения доступа к разрешенным зависимостям из шаблона карта разрешения будет доступна в области маршрута, в разделе $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
}
person Daniel Lizik    schedule 08.02.2017