简体   繁体   English

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

[英]AngularJS sharing data form AJAX $http request

I have the following controllers: 我有以下控制器:

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;
         }
     }
  });

My HTML is as follows: 我的HTML如下:

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

    </div>
</div>

So basically when I receive the AJAX request I want both the controllers to get updated with the data 因此,基本上,当我收到AJAX请求时,我希望两个控制器都更新数据

The best way would be to return the promise from $http.get : 最好的方法是从$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;  
      });
   }
});

You can broadcast custom message to rootScope and Your controllers will get this message and handle it. 您可以将自定义消息广播到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;
         }
     }
});

You could handle it in many ways. 您可以通过多种方式处理它。 One simple way is to cache the promise and return it. 一种简单的方法是缓存诺言并返回。

Example:- 例:-

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;
             }));
         }
     }
  });

and in controller: 并在控制器中:

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;  
      });
   }
});

Caching a promise will make sure that it really does not matter who makes the first call and you always make the same service call to get the data and service will manage data caching via promise and prevent any duplicate calls. 缓存诺言将确保与谁进行第一个调用无关紧要,并且您始终进行同一服务调用以获取数据,并且服务将通过诺言管理数据缓存并防止任何重复调用。

Another practice is to implement a one-way data flow using flux pattern . 另一种实践是使用通量模式实现单向数据流。 Where you create stores that maintains data and it will make ajax call via a dispatcher and emits event to the subscribers of change event. 您在哪里创建存储数据的存储,它将通过分派器进行ajax调用,并将事件发送给change事件的订阅者。 There is an angular library ( flux-angular ) that can be used as well to implement this pattern. 还有一个角度库( flux-angular )也可以用来实现此模式。 This will really help synchronize data between multiple components regardless of whether they are parent/child or siblings and regardless of who makes the first call etc.. 这确实将有助于在多个组件之间同步数据,而不管它们是父/子还是同级,以及谁是第一个调用者等等。

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

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