$rootScope 属性 值在服务中未定义

$rootScope property value undefined in service

我在数据库中有一个 table,我需要在我的网站上进行任何其他操作之前访问它。我得到的值,我将在不同的控制器、指令、服务等中使用所有这些值。我认为存储这些值的最佳位置是在 $rootScope 中,因此为此,我做了以下操作:

obApp.run(function($rootScope, ngProgress, $timeout) {
  $.post('phpProcessingPage', function(data){
   $rootScope.domains = JSON.parse(data); //this "domains" property is what i'm interested in
  })
})

我顺利取回了域,所以一切都很好。问题是,当我将 $rootScope 注入服务时:

obApp.factory('requestOrigin', ['$rootScope', function($rootScope){
   console.log($rootScope.domains); //this is undefined at this point
   return $rootScope.domains; //returns undefined
}]);

预计不会有任何内容,因为响应将在服务代码执行后出现。

问题是,我在多个控制器中使用该工厂代码,但我不知道如何延迟它的执行,以便它等到我从 ajax 调用中取回数据。

我试过进行广播,但没有办法(据我所知)延迟工厂的 retun,即使在某些时候我确实得到了结果。我将如何解决我遇到的这个问题?

答案:

为此取消 $rootScope 的使用。我使用服务返回结果的控制器如下所示:

oApp.controller(['serviceName', function(serviceName){
    serviceName.then(function(response){
      //here i have the data from the ajax call, the service made
      //other things to do
    });
}]);

服务看起来像这样:

obApp.factory(['serviceName','$http', function(serviceName, $http){
    return $http.post('phpProcessingPage.php', {cache: true});
}]);

而不是使用 jquery $ service 你应该使用 angular $http which return 你可以附加到你的范围的承诺。根据定义,promise 会立即定义,当 promise 得到解决时,您的范围将被填充。最重要的是 angular 模板完全理解 promises 并会在准备就绪后立即在视图中显示您的模型。

我会说你需要使用 promises 重新设计这个小东西。

使用服务来存储和 return 此数据,并且从您的 controllers/directive/etc,您可以执行以下操作:

DomainService.getDomains().then(function () {
    // Do whatever you need, here you'll have the data
});

现在服务应该 return 数据,或者当应用第一次 运行 时没有数据时从服务器获取它:

// Domain service
var domains;

var getDomains = function () {
    // using angular's $q service
    var deferred = $q.defer();

    if (domains) {
        // returns the data without going to the server
        deferred.resolve(domains);
    }  
    else {
        // fetches the data the first time, also notice angular's $http service
        $http.post('phpProcessingPage', data).then(function(response)
            domains = response;
            deferred.resolve(domains);
        });
    }

    return deferred.promise;
}