2013-03-01 94 views
14

我在从填充到我的视图中的服务中获取数据时遇到问题。我有一个服务定义为这样AngularJS从服务中加载数据

app.factory('nukeService', function($rootScope, $http) { 
    var nukeService = {}; 

    nukeService.nuke = {}; 

    //Gets the list of nuclear weapons 
    nukeService.getNukes = function() { 
     $http.get('nukes/nukes.json') 
      .success(function(data) { 
       nukeService.nukes = data; 
      }); 

     return nukeService.nukes; 
    }; 

    return nukeService; 
}); 

和我的控制器

function NavigationCtrl($scope, $http, nukeService){ 



    /*$http.get('nukes/nukes.json').success(function(data) { 
     $scope.nukes = data; 
    });*/ 

    $scope.nukes = nukeService.getNukes(); 

} 

如果我使用$ http.get来自控制器的数据填充正常,但是,如果我尝试调用从数据这项服务,我什么也得不到。我明白查询是异步的,但我很难理解如何在数据返回时填充$ scope变量。我可以使用$ rootcope来广播一个事件并在控制器中监听它,但这看起来并不是实现这一点的正确方法。我真的很感激任何关于如何以正确方式做到这一点的建议。

回答

27

我想这应该解决您的问题

app.factory('nukeService', function($rootScope, $http) { 
    var nukeService = {}; 

    nukeService.data = {}; 

    //Gets the list of nuclear weapons 
    nukeService.getNukes = function() { 
     $http.get('nukes/nukes.json') 
      .success(function(data) { 
       nukeService.data.nukes = data; 
      }); 

     return nukeService.data; 
    }; 

    return nukeService; 
}); 

function NavigationCtrl($scope, $http, nukeService){ 

    $scope.data = nukeService.getNukes(); 

    //then refer to nukes list as `data.nukes` 

} 

这是对象引用的一个问题。

当你打电话给nukeService.getNukes()你得到一个对象的引用a那么你的变量$scope.nukes指的是内存位置。

远程服务器的呼叫后,当您设置nukeService.nukes = data;你是不是从引用对象a反对b改变a而是要更改nukeService.nukes的对象。但是你的$scope.nukes不知道这个重新分配,它仍然指向对象a

我在这种情况下的解决方案是通过一个对象a与属性data,然后仅将数据属性,而不是改变参考更改为a

+0

这工作,但我可以问为什么?我假设它与.data有关,它是json数据的容器,而不是直接传递它。顺便说一句,谢谢你的及时回复! – jamesamuir 2013-03-01 16:09:13

+0

如果它正在工作,请将答案标记为接受 – 2013-03-01 16:17:18

+0

标记为已回答。谢谢你的解释。 – jamesamuir 2013-03-01 17:52:17

9

这应该是如下。正如NickWiggill的评论所述,如果我们不返回承诺,undefined将被分配给nukeService.data。

app.factory('nukeService', function($rootScope, $http) { 
    var nukeService = {}; 
    //Gets the list of nuclear weapons 
    nukeService.getNukes = function() { 
     return $http.get('nukes/nukes.json'); 
    }; 

    return nukeService; 
}); 


    function NavigationCtrl($scope, $http, nukeService){ 
    nukeService.getNukes().then(function(response){ 

     $scope.data = response.data; 
    }); 

    } 
3

我只是直接从服务中暴露数据,并有一个方法来初始化这些数据。这有什么问题?

服务:

app.factory('nukeService', function($scope, $http) { 
    var data = {}; 
    data.nukes = []; 

    //Gets the list of nuclear weapons 
    var getNukes = function() { 
     $http.get('nukes/nukes.json').success(function(data) { 
       data.nukes = data; 
     }); 
    }; 

    // Fill the list with actual nukes, async why not. 
    getNukes(); 

    return { 
     data : data 
     // expose more functions or data if you want 
    }; 
}); 

控制器:

function NavigationCtrl($scope, nukeService){ 
    $scope.data = nukeService.data; 
    //then refer to nukes list as `$scope.data.nukes` 
}