https成功时在控制器之间传递数据

时间:2018-01-17 09:13:25

标签: javascript angularjs performance

我试图在每个http请求成功时在控制器之间传递数据。那说,这是一个层次结构

<div ng-controller="ParentCtrl as parent">
   <div ng-controller="ChildOneCtrl as chi1"></div>
   <div ng-controller="ChildTwoCtrl as chi2"></div>
   <div ng-controller="ChildThreeCtrl as chi3"></div>
</div>

在每个下一个控制器中加载数据取决于前一个控制器,即http请求成功时。

ChildOneCtrl:

function ChildOneCtrl ($scope, sharedService) {

   var chi1 = this;

   sharedService.getChildOneData()
       .then(function (res) {
            $rootScope.$emit('childOneDataEmited', res.data);
       }).catch(function (err) {
           console.log(err);
       });
}

ChildTwoCtrl:

function ChildTwoCtrl ($scope, $rootScope, sharedService) {

   var chi2 = this;

   var onEmitChildOne = $rootScope.$on('childOneDataEmited', function (event, data) {
        getData(data);    
   });

   $scope.$on('$destroy', onEmitChildOne);

   function getData(data){

       var chi1Data = data;

       if(chi1Data.uEnabled){
           sharedService.getChildTwoData()
              .then(function (res) {
                  $rootScope.$emit('childTwoDataEmited', res.data);
              }).catch(function (err) {
                 console.log(err);
              });
       }
   }
}

ChildThreeCtrl:

function ChildThreeCtrl ($scope, $rootScope, sharedService) {

   var chi3 = this;

   var onEmitChildThree = $rootScope.$on('childTwoDataEmited', function (event, data) {
        getData(data);    
   });

   $scope.$on('$destroy', onEmitChildThree);

   function getData(data){

       var chi2Data = data;

       sharedService.getChildThreeData()
          .then(function (res) {
               //to do some data manipulation
               console.log(res)
               console.log(chi2Data)
          }).catch(function (err) {
              console.log(err);
          });
   }
}

虽然这可以完成工作,但层次结构可能会发生变化,变得更深,所以我想知道是否有更好的方法可以做到这一点所以我不会过度使用事件?

1 个答案:

答案 0 :(得分:2)

为什么不通过sharedService分享自己的数据? 从第一个控制器获取数据后,只需将其分配给sharedService和子控制器(第二个)中的共享变量,只需为此共享变量设置watch即可。像这样:

function ChildOneCtrl ($scope, sharedService) {

   var chi1 = this;

   sharedService.getChildOneData()
       .then(function (res) {
            sharedService.sharedData = res.Data;
       }).catch(function (err) {
           console.log(err);
       });
}

function ChildTwoCtrl ($scope, $rootScope, sharedService) {

   var chi2 = this;

   $scope.watch('sharedService.sharedData', function(newValue) {
         // do something like calling another endpoint using http.
   });
}  

我没有尝试过,可能会失败,但想法是通过服务共享数据。

<强>更新
另一种方法是有两个then()或更多:

function sharedService($q, $http) {
   var service = {
       sharedData1Promise: { then: function() {} },
       sharedData2Promise: { then: function() {} },
       sharedData3Promise: { then: function() {} },
       getSomeData1: getSomeData1
   };

   function getSomeData1() {
       sharedData1Promise = $http.get( /* what ever is here */ );
       return sharedData1Promise;
   }

   function getSomeData2() {
      sharedData2Promise = $http.get( /* what ever is here */ );
      return sharedData2Promise;
   }

   function getSomeData3() {
      sharedData3Promise = $http.get( /* what ever is here */ );
      return sharedData3Promise;
   }

   return service;
}

function ChildOneCtrl ($scope, sharedService) {

   var chi1 = this;

   sharedService.getSomeData1()
       .then(function (res) {
            /* do something */
       }).catch(function (err) {
           console.log(err);
       });
}

function ChildTwoCtrl ($scope, sharedService) {

   var chi2 = this;

   sharedService.sharedData1Promise
       .then(function (res) {
           sharedService.getSomeData2();
           /* do something with data coming from the first child calling getSomeData1 method */
       }).catch(function (err) {
           console.log(err);
       });
}