简体   繁体   English

在AngularJS中的控制器之间共享来自API的数据

[英]Sharing data from API between controllers in AngularJS

I have a parent controller with some children controllers, and I want them all to share the same data that I retrieve from an Api service. 我有一个带有某些子控制器的父控制器,我希望它们所有人共享从Api服务检索的相同数据。

Controllers: 控制器:

var app = angular.module('mymodule',[]);

app.controller('main', ['$scope', 'Api', function($scope, Api) {
    var getList1 = Api.getList1()
      .then(function(resp) {
        $scope.list1 = resp.data;
      });

    var getList2 = Api.getList2()
      .then(function(resp) {
        $scope.list2 = resp.data;
      });
}]);

app.controller('child1', ['$scope', function($scope) {
    $scope.list1 = ?
    $scope.list2 = ?
}]);

app.controller('child2', ['$scope', function($scope) {
    $scope.list1 = ?
}]);

View: 视图:

<div ng-controller="main">
    <ul>
        <li ng-repeat="list in list1">
            {{list.item}}
        </li>
    </ul>
    <div ng-controller="child1">
        <ul>
            <li ng-repeat="list in list1">
                {{list.item}}
            </li>
        </ul>
        <ul>
            <li ng-repeat="list in list2">
                {{list.item}}
            </li>
        </ul>
    </div>
    <div ng-controller="child1">
        <ul>
            <li ng-repeat="list in list1">
                {{list.item}}
            </li>
        </ul>
    </div>
</div>

I tried to use this solution with Angular's events mechanism ($on, $emit). 我试图将此解决方案与Angular的事件机制($ on,$ emit)一起使用。
The problem was that I had to figure out which child controller is active and send the data when the promise has resolved. 问题是我必须弄清楚哪个子控制器处于活动状态,并在诺言解决后发送数据。 It ends with ugly spaghetti code... 它以丑陋的意大利面条代码结尾...

Well, the best way is to use a service to have your API handling atomar placed inside your application. 好吧,最好的方法是使用service将API处理原子库放置在应用程序中。 This fiddle shows you how you could achieve what you try to. 这个小提琴向您展示了如何实现自己的目标。 By using AngularJS services you will be able to share the same data, objects and functions between controllers and let them interact with eachother. 通过使用AngularJS服务,您将能够在控制器之间共享相同的数据,对象和功能,并使它们彼此交互。 This is undepending on the amount of your controllers inside your application. 这与应用程序内的控制器数量无关。

The following example is a full working API service with real HTTP-Requests and a real AngularJS service handling. 以下示例是具有真实HTTP请求和真实AngularJS服务处理功能的完整API服务。 It will help you by implement such logic inside your application. 通过在您的应用程序内部实现此类逻辑,将为您提供帮助。 Please dont forget to check out the fiddle demo . 请不要忘记查看fiddle demo

View 视图

<div ng-controller="MyCtrl">
   <h1>
    MyCtrl
   </h1>
   <button ng-click="clearData()">
    Clear data by using MyCtrl
   </button>
   <div ng-repeat="user in users">
     <p>
       Username: {{ user.name }}
     </p>
   </div>
</div>
<br /><br />
<div ng-controller="MyOtherCtrl">
 <h1>
  MyOtherController
 </h1>
   <button ng-click="clearData()">
    Clear data by using MyOtherController
   </button>
   <div ng-repeat="user in users">
     <p>
       Username: {{ user.name }}
     </p>
   </div>
</div>

AngularJS Application AngularJS应用

var myApp = angular.module('myApp',[]);;


myApp.controller('MyCtrl', function ($scope, apiService) {
   $scope.users = apiService.getResponseData();
   $scope.$watch(function () { return apiService.getResponseData()}, function (newValue, oldValue) {
     $scope.users = newValue
   });

   $scope.clearData = function () {
        apiService.reset();
   }
});
myApp.controller('MyOtherCtrl', function ($scope, apiService) {

   apiService.loadData();

   $scope.$watch(function () { return apiService.getResponseData()}, function (newValue, oldValue) {
     $scope.users = newValue
   });

   $scope.clearData = function () {
        apiService.reset();
   }
})


myApp.service('apiService', function ($http) {

  var responseData = null;

  return {
    loadData: function () {
      return $http({
         url: 'https://jsonplaceholder.typicode.com/users',
         method: 'GET'
      }).then(function (response) {
         responseData = response.data
      });
    },
    getResponseData: function () {
       return responseData
    },
    reset: function () {
       responseData = null;
    }
  }
});

As your data is in the scope of the parent controller, you can access it in children controllers with $scope.$parent : 由于数据在父控制器的范围内,因此可以使用$scope.$parent在子控制器中访问它:

app.controller('child1', ['$scope', function($scope) {
    $scope.list1 = $scope.$parent.list1;
    $scope.list2 = $scope.$parent.list2;
}]);

Write your children as directives, and then you can inject data on the scope. 将孩子写为指令,然后可以将数据注入示波器。

yourModule.directive('child1', function() {
    return {
       scope: {list1:'=',
       controller: function (scope) {
           //not sure you even need a controller, but it might look like this
           scope.doSomething =  function() {
              //access scope.list1 here
           }
       },
       template: '<ul><li ng-repeat="list in list1">{{list.item}}<li><ul>'
    }
}

Usage: 用法:

<child1 list1="list1"></child1>

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

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