繁体   English   中英

AngularJS从AJAX $ http请求中共享数据

[英]AngularJS sharing data form AJAX $http request

我有以下控制器:

angular.module('app').controller('ParentCtrl', function(Service) {

   var list = []
   var init = function () {
      Service.query().success(function() {
          list = Service.getList();  
      });
   }
});

angular.module('app').controller('ChildCtrl', function(Service) {

   var list = []
   var init = function () {
      list = Service.getList();
   }
});

angular.module('app').factory('Service', function($http) {

     list = []
     return {
         query : function() {
             $http.get('/path/to/my/api').success(function(data){
                list = data
             })
         },
         getList: function() {
             return list;
         }
     }
  });

我的HTML如下:

<div ng-controller="ParentCtrl as parent">
    <div ng-controller="ChildCtrl as child">

    </div>
</div>

因此,基本上,当我收到AJAX请求时,我希望两个控制器都更新数据

最好的方法是从$http.get返回承诺:

angular.module('app').factory('Service', function($http) {
   var promise;
   return {
     getList: function() {
         if (promise) {
             return promise;
         }

         promise = $http.get('/path/to/my/api');
         return promise;
     }
   }
});

angular.module('app').controller('ParentCtrl', function(Service) {    
   var list = [];
   var init = function () {
      Service.getList().then(function(response) {
          list = response.data;  
      });
   }
});

angular.module('app').controller('ChildCtrl', function(Service) {
   var list = [];
   var init = function () {
      Service.getList().then(function(response) {
          list = response.data;  
      });
   }
});

您可以将自定义消息广播到rootScope,然后您的控制器将获得此消息并进行处理。

angular.module('app').controller('ParentCtrl', function($rootScope, $scope, Service) {

   $scope.list = [];

   $scope.$on('Service:list', function(event, data){
       $scope.list = data;
   });
});

angular.module('app').controller('ChildCtrl', function($rootScope, $scope, Service) {

   $scope.list = [];

   $scope.$on('Service:list', function(event, data){
       $scope.list = data;
   });

   Service.query(); // run once, get in both controllers
});

angular.module('app').factory('Service', function($rootScope, $http) {
     var list;

     return {
         query : function() {
             $http.get('/path/to/my/api').success(function(data){
                list = data;
                $rootScope.$broadcast('Service:list', list);
             })
         },
         getList: function() {
             return list;
         }
     }
});

您可以通过多种方式处理它。 一种简单的方法是缓存诺言并返回。

例:-

angular.module('app').factory('Service', function($http, $q) {
     var listPromise;
     return {
         getList: function() {
             //If promise is already present then 
             return listPromise || (listPromise = $http.get('/path/to/my/api').then(function(response){
                return response.data;
             })
             //Use the below 2 blocks (catch and finally) only if you need.
             //Invalidate in case of error
             .catch(function(error){ 
                  listPromise = null;
                  return $q.reject(error);
             })
            //Use finally to clean up promise only if you only need to avoid simultaneous request to the server and do not want to cache the data for ever.
            .finally(function(){ 
                listPromise = null;
             }));
         }
     }
  });

并在控制器中:

angular.module('app').controller('ParentCtrl', function(Service) {
   var list = [];
   var init = function () {
      Service.getList().then(function(data) {
          list = data;  
      });
   }
});

angular.module('app').controller('ChildCtrl', function(Service) {

   var list = [];
   var init = function () {
      Service.getList().then(function(data) {
          list = data;  
      });
   }
});

缓存诺言将确保与谁进行第一个调用无关紧要,并且您始终进行同一服务调用以获取数据,并且服务将通过诺言管理数据缓存并防止任何重复调用。

另一种实践是使用通量模式实现单向数据流。 您在哪里创建存储数据的存储,它将通过分派器进行ajax调用,并将事件发送给change事件的订阅者。 还有一个角度库( flux-angular )也可以用来实现此模式。 这确实将有助于在多个组件之间同步数据,而不管它们是父/子还是同级,以及谁是第一个调用者等等。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM