angular resolve возвращает функцию вместо значения

#javascript #angularjs

#javascript #angularjs

Вопрос:

Я пытаюсь реорганизовать некоторый код из моего контроллера в «разрешение» маршрута, и у меня возникают проблемы с получением правильного возвращаемого значения resolve . Я думаю, что проблема либо из-за моего непонимания замыканий js, либо из-за библиотеки $ q в angular.

В маршрутизации:

 .when('/countries/:id', {
      templateUrl: 'country/country.html',
      controller: 'countryCtrl',
      resolve: {
        ActiveCountry: ['CountryData', '$q', '$route', function(CountryData, $q, $route) {
          var defer = $q.defer();
          CountryData($route.current.params.id).then(function(data){
            console.log(data);
            defer.resolve(data);
          });
          return defer.promise;
        }]
      }
    })
 

console.log In этот блок возвращает правильный объект JSON из вызова api. Однако, когда он передается в контроллер, контроллер возвращает функцию из CountryData службы:

 .controller('countryCtrl', [
  'CountryData',
  '$routeParams',
  '$scope',
  function (ActiveCountry, $routeParams, $scope) {
    var countryId = $routeParams.id;
    console.log(ActiveCountry);
    $scope.mapId = $routeParams.id.toLowerCase();
    $scope.country = ActiveCountry;
  }
]);
 

Значение маршрутизации console.log равно:
Object {countryName: "Spain", currencyCode: "EUR", fipsCode: "SP", countryCode: "ES", isoNumeric: "724"…}

но журнал консоли контроллера — это функция из моего CountryData сервиса:

 function (countryId) {
      var defer = $q.defer();
      $http.get(COUNTRIES_PATH   'amp;country='   countryId   API_AUTH, { cache: true }).success(function (data) {
        defer.resolve(data.geonames[0]);
      });
      return defer.promise;
    } 
 

Почему объект из маршрутизации неправильно передается в контроллер?

Кроме того, зачем мне нужно использовать $q маршрутизатор, если он уже встроен в CountryData сервис? Без использования $q в маршрутизации он возвращает функцию, а не возвращаемое значение функции.

Комментарии:

1. why do I need to use $q in the router when it is already built into the CountryData service Вам не нужно. Просто заставьте CountryData вернуть обещание.

Ответ №1:

Вы вводите ‘CountryData’, а затем ActiveCountry для аргументов вашего контроллера. Так что они не совпадают.

Это должно быть «CountryData» и CountryData

 controller('countryCtrl', [
  'CountryData',
  '$routeParams',
  '$scope',
  function (CountryData, $routeParams, $scope) {
    var countryId = $routeParams.id;
    console.log(ActiveCountry);
    $scope.mapId = $routeParams.id.toLowerCase();
    $scope.country = ActiveCountry;
  }
]);
 

Комментарии:

1. хороший улов! снялся на этом в течение нескольких часов

Ответ №2:

Angular автоматически разрешит любые обещания, которые возвращаются из функций в свойстве resolve . Итак, ваше свойство resolve должно выглядеть следующим образом:

 resolve: {
  ActiveCountry: ['CountryData', '$q', '$route', function(CountryData, $q, $route) {
    return CountryData($route.current.params.id);
  }
}
 

Перед вызовом вашего метода контроллера $routeProvider будут повторно выполнены все обещания, которые передаются контроллеру в качестве параметров. Дополнительные сведения см. в разделе $routeProvider.when().

Комментарии:

1. похоже, может быть, проблема в моей службе? Если я устанавливаю значение resolve console.log(CountryData($route.current.params.id); , оно регистрирует не возвращаемое значение, а саму функцию: Object {then: function, catch: function, finally: function} Однако в Chrome console network я вижу, что служба выполняет вызов API так, как должна.