Javascript 在加载控制器之前,强制AngularJS服务返回数据

Javascript 在加载控制器之前,强制AngularJS服务返回数据,javascript,angularjs,angularjs-service,Javascript,Angularjs,Angularjs Service,我在Angular中有一个服务,它使用我的API获取用户信息并将其提供给我的控制器。它是这样设置的: angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives', 'ngResource', 'infinite-scroll', 'ui.bootstrap', 'ngCookies', 'seo']) .service('userInfo', function($http, $cookies){

我在Angular中有一个服务,它使用我的API获取用户信息并将其提供给我的控制器。它是这样设置的:

angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives', 'ngResource', 'infinite-scroll', 'ui.bootstrap', 'ngCookies', 'seo'])
  .service('userInfo', function($http, $cookies){
    $http.get('/api/users/' + $cookies.id).
    success(function(data) {
      var userInfo = data.user[0];

      return userInfo;
    });
  }). // other stuff comes after this
angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives', 'ngResource', 'infinite-scroll', 'ui.bootstrap', 'ngCookies', 'seo'])
    .service('userInfo', function ($http, $cookies) {
    var promise = $http.get('/api/users/' + $cookies.id).
    success(function (data) {
        var userInfo = data.user[0];
        return userInfo;
    });
    return promise;
}) // other stuff comes after this
在我的控制器中,我包括如下内容:

function userProfile($scope, $cookies, userInfo, $http, $resource, $routeParams, $rootScope){
    $scope.user = userInfo;
    console.log('user info is')
    console.log(userInfo);
这不返回任何数据,而如果我将相同的服务函数放在控制器本身中,它会返回很好的结果。我错过了什么?以前从未在Angular中使用过DI/服务,因此在某些地方可能是一个简单的错误


我需要确保服务在加载控制器之前返回数据。如何实现这一点

您的
userInfo
服务必须返回
$http
返回的承诺。然后,该承诺将被注入到控制器中,并且一旦该承诺成功解析,视图将被更新


如果您根本不希望在
userInfo
解析之前呈现视图,则应在路由上设置
resolve
属性,并将服务注入其中:

$routeProvider.when('/profile', {
    templateUrl: 'profile',
    controller: userProfile,
    resolve: {
         userInfoData: function ($q, userInfo) {
             return userInfo;
         }
    }
});

然后,只需将
userInfoData
插入控制器,而不是
userInfo
服务。

您可以让工厂返回如下承诺:

angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives', 'ngResource', 'infinite-scroll', 'ui.bootstrap', 'ngCookies', 'seo'])
  .service('userInfo', function($http, $cookies){
    $http.get('/api/users/' + $cookies.id).
    success(function(data) {
      var userInfo = data.user[0];

      return userInfo;
    });
  }). // other stuff comes after this
angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives', 'ngResource', 'infinite-scroll', 'ui.bootstrap', 'ngCookies', 'seo'])
    .service('userInfo', function ($http, $cookies) {
    var promise = $http.get('/api/users/' + $cookies.id).
    success(function (data) {
        var userInfo = data.user[0];
        return userInfo;
    });
    return promise;
}) // other stuff comes after this
在控制器中,执行以下操作:

function userProfile($scope, $cookies, userInfo, $http, $resource, $routeParams, $rootScope){
    userInfo.then(function(data){
        $scope.user = data;
    });
}

这可以保证,无论何时使用该服务,它总是同步地向您提供数据,您不必在加载控制器之前加载任何数据。

您可以这样将资源对象分配给变量
return$http.get(url)

我遇到了同样的问题,在这个问题中,我必须使用$resource将数据加载到服务中,然后将数据加载到$scope中。 我不想直接返回承诺,然后在控制器中使用解析器(正如@zsong所写),而是像@Joseph Silber所指出的那样,在服务中使用一次所有的魔法,并使用将承诺直接分配给$scope的功能,所以我做了以下工作:

return function($scope){promise.then(function(data){$scope.user = data})};
并在控制器中使用,如下所示:

userInfo($scope);

虽然没有太大的改进,但它让我的控制器有了更清晰的语法,希望它能在三年后有所帮助

我需要所有控制器/路由都可以使用这些数据,是否有一种特殊的方法可以将其注入一次,这样我就不必为每条路由重复20多次?@Jascination-我不知道。我想您只需要为所有需要它的路由设置
resolve:resolveUserInfo
。我已经尝试了您的解决方案,但它仍然在做同样的事情-在数据解析之前加载控制器。我知道这种情况可能不应该发生,因为
resolve
,我假设这是一个异步/回调问题,因为
resolveUserInfo
函数在返回之前没有完成加载数据。@Jascination-您是否已从服务返回
$http
承诺?是否有可能在不使用路由的情况下完成此操作?承诺可以直接分配给
$scope
。当承诺解析时,Angular会自动更新视图。请注意,Angular 1.2+中的承诺不会自动展开。这真的有效吗?我看不是响应中的实际数据您可以简化您的console.log如下:
console.log('user info is',userInfo)@EddieMongeJr真的吗?我不知道,谢谢。