Почему я не могу установить/получить $rootScope?

Я пытаюсь установить значение в $rootScope в .run() и пытаюсь получить его в службе, но похоже, что оно не определено. Все остальное в .run() и в сервисе работает нормально.

.run(function($ionicPlatform, $translate, $rootScope) {
  document.addEventListener("deviceready",function(){ onDeviceReady($rootScope); }, false);

  function onDeviceReady($rootScope) {
    if(typeof navigator.globalization !== "undefined") {
      navigator.globalization.getPreferredLanguage(function(language) {
        $rootScope.language='en'; //(language.value).split('-')[0];
        $translate.use((language.value).split("-")[0]).then(function(data) {
          console.log("SUCCESS -> " + data);
        }, function(error) {
          console.log("ERROR -> " + error);
        });
      }, null);
    }
  }
})


.service('Webcache', function ($http, $q, apiHost, $rootScope) {
    return {
        getDataBySection: function (section, version, params) {
            var params = params || {};
            var host = apiHost;
            var deferred = $q.defer();
            var start = new Date().getTime();

            params.lang = $rootScope.language;

            $http.get('http://'+ host +'/api/'+ version +'/'+ section, {
                cache: true,
                params: params
            }).success(function (response) {
                deferred.resolve(response);
            }).error(function (response){
                deferred.resolve(false);
            });
            return deferred.promise;
        }
    };
})

person Edo    schedule 01.02.2016    source источник
comment
Я предполагаю, что событие deviceReady не сработало в тот момент, когда вы пытаетесь его использовать. Лучшим решением было бы переместить язык из области видимости в службу и заставить службу использовать обещания для доступа к текущему языку (так что метод getLanguage() возвращает обещание. Кроме того, не используйте устаревшие success, error методы на результат $http.get, просто используйте then(), и вы можете напрямую вернуть response.   -  person Duncan    schedule 01.02.2016


Ответы (2)


Вы вообще не должны привязываться к событию onDeviceReady. Ionic дает вам совместимый с angular способ справиться с этим: $ionicPlatform.ready() который возвращает обещание. Используя это, ваш код будет выглядеть примерно так:

.run(function($ionicPlatform, $translate, $rootScope, $q, $log) {
   $rootScope.languagePromise = $ionicPlatform.ready()
   .then(function() {
        return $q(function(resolve, reject) {
            if(angular.isDefined(navigator.globalization)) {
                navigator.globalization.getPreferredLanguage(function(language) {
                    $translate.use((language.value).split("-")[0]).then(function(data) {
                        $log.debug("SUCCESS -> " + data);
                        resolve(language);
                    }, function(error) {
                        $log.debug("ERROR -> " + error);
                        reject(error);
                    });
                }, null);
            } else { resolve('en'); }
        });
    });

})

Это помещает обещание в область действия, которую вы можете использовать в любое время, чтобы получить язык либо немедленно (если инициализация завершена), либо когда он станет доступным.

.service('Webcache', function ($http, apiHost, $rootScope) {
    return {
        getDataBySection: function (section, version, params) {
            params = params || {};
            var host = apiHost;
            return $rootScope.languagePromise.then(function(language) {
                params.lang = language;
                return $http.get('http://'+ host +'/api/'+ version +'/'+ section, {
                    cache: true,
                    params: params
                }).catch(function (){
                    return false;
                });
            });
        }
    };
})

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

person Duncan    schedule 01.02.2016

Кажется, что устройство не готово, когда вы пытаетесь выполнить код, вы пытались использовать $ionicPlatform.ready? что-то вроде этого:

.run(appRun);
appRun.$inject = ['$ionicPlatform', '$translate', '$rootScope'];
function appRun ($ionicPlatform, $translate, $rootScope) {
    $ionicPlatform.ready(function () {
      if(typeof navigator.globalization !== "undefined") {
        navigator.globalization.getPreferredLanguage(function(language) {
          $rootScope.language='en'; //(language.value).split('-')[0];
          $translate.use((language.value).split("-")[0]).then(function(data) {
            console.log("SUCCESS -> " + data);
          }, function(error) {
            console.log("ERROR -> " + error);
          });
        }, null);
      }
    });
}
person Ravish    schedule 01.02.2016