如何使用Angular服务在控制器/页面之间共享数据?

如何使用Angular服务在控制器/页面之间共享数据?

问题描述:

我正在创建一个“Web Planner”,用户必须在不同页面上完成若干步骤才能创建我们的服务订单。我知道我需要使用服务来共享整个Planner的某些数据,但我仍然不确定如何去做。如何使用Angular服务在控制器/页面之间共享数据?

问题是,用户不一定每次都按顺序进行。他们可以在任何页面上停止,然后再回来并恢复,因此我需要一种方法来管理一些API数据,以便如果用户在共享相同数据的两页中的一页上,数据将通过API从服务器获取或者如果数据已被采用,则简单分配。

现在我唯一想到的方法是将API请求放入我的服务中,然后当我运行诸如OrderService.get()之类的服务时,服务将处理逻辑以检查数据是否已从服务器获取。如果是的话,它只是一个简单的任务,如$scope.model = OrderService.get(),但问题是,如果数据尚未加载,那么我需要在某处等待数据,因此一个简单的赋值操作不会足够了。

此服务可能是这个样子:

app.factory('OrderService', function(){ 
    var orders = []; // This is the actual data 

    var service = {}; 

    service.get = function(id){ 
     if(orders.length){ 
      return orders; // This means there is already data available 
     }else{ 
      // This is where I am not sure what to do... 
      // Maybe... 
      var promise = API.Orders.getAllOrders({id : id}, function(res){ 
        // Not sure about how to implement this part 
      }).$promise; 

      return promise; 
     } 
    } 


}) 

没有人有任何其他的想法?

+0

这真的是罕见的,没有人知道的事该怎么办? – 2014-09-12 16:16:36

由于您的调用是异步的,要做到这一点的唯一方法是通过承诺

app.service('OrderService', function($q){ // import $q ; the angularjs promise 

    var orders = []; // This is the actual data 

    var service = {}; 

    service.get = function(id){ 
     var deferred = $q.defer(); // create a unit of work to be done; a promise 

     if(orders.length){ // if data is already available, resolve the promise 
      deferred.resolve(orders); // This means there is already data available, so mark as resolved and successful 
     }else{ 
      // make your async call since you don't have data 
      API.Orders.getAllOrders({id : id}, function(response){ 
       // here you can actually modify the response before it goes back to your controller 
       deferred.resolve(response); 
      }, function(reason){ // failure scenario 
       deferred.reject(reason); 
      }) 

     } 
     return deferred.promise; // always return promise 
    } 
}) 
+0

哦,哇,我不认为使用deferred.resolve()来解决他们已经存在的订单。这应该工作!我会试一试。谢谢 – 2014-09-12 18:28:49

只要一直返回一个承诺,数据是否已经存在,或通过调用服务器获取。在您的例子..

if(orders.length){ 
     return $q.when(orders); // This means there is already data available 
    }else{ 
     // This is where I am not sure what to do... 
     // Maybe... 
     var promise = API.Orders.getAllOrders({id : id}, function(res){ 
       // Not sure about how to implement this part 
     }).$promise; 

     return promise; 
    } 

请记住,我还是个初学者(通过大量阅读的文档),所以这可能不是100%正确的。

您的服务将是这样的:

app.factory('OrderService', function($q){ 
    var orders = []; // This is the actual data 

    return { 
     getData: function(id){ 
     var deferred = $q.defer(); 

     if(orders.length){ 
      deferred.resolve(orders); // This means there is already data available 
     }else{ 
      $http.get('/api/get/data/' + id) 
       .success(function(data) { 
        deferred.resolve(data); 
       }) 
       .error(function(){ 
        deferred.reject(); 
       }); 
     } 

     return deferred.promise; 
    } 
}) 

,然后在你的控制器,你只需要使用它像这样:

app.controller('MainCtrl', function($scope, OrderService) { 
    var id = 1; 
    $scope.data = OrderService.getData(id); 
});