如何通过AngularJS中的一个调用在多个控制器($scope)中插入相同的数据

How I insert a same data in multiple controllers ($scope) with one call in AngularJS?

本文关键字:scope 插入 控制器 数据 一个 AngularJS 何通过 调用      更新时间:2023-09-26

我正在使用一个工厂来调用同一页面中的两个控制器,但我不希望这个调用AJAX两次。我尝试使用$q.defer(),但它不起作用!

代码:

(function () {
    'use strict';
    var app = angular.module('globalApp', []).config([
        '$interpolateProvider', '$httpProvider',
        function ($interpolateProvider, $httpProvider) {
            delete $httpProvider.defaults.headers.common['X-Requested-With'];
            $interpolateProvider.startSymbol('<%');
            $interpolateProvider.endSymbol('%>');
        }
    ]);
    // Index Store List
    app.controller('IndexController', ['$scope', '$storeList',
        function ($scope, $storeList) {
            $scope.stores = [];
            $storeList.getStoreList().then(function (stores) {
                $scope.stores = stores;
            });
        }]);
    // Footer Store List
    app.controller('StoreListController', [
        '$scope', '$storeList',
        function ($scope, $storeList) {
            $scope.stores = [];
            $storeList.getStoreList().then(function (stores) {
                $scope.stores = stores;
            });
        }
    ]);
    
    // Factory call list os stores
    app.factory('$storeList', function ($http, $q) {
        var stores = [];
        return {
            getStoreList: function () {
                //is a request needed?
                if (stores.length > 0) {
                    var deferred = $q.defer();
                    deferred.resolve(stores);
                    return deferred.promise;
                }
                var uri = rootUrl + 'getStoreList';
                var responsePromise = $http.get(uri);
                return responsePromise.then(function (result) {
                    var data = result.data;
                    //modify collection of stores...
                    if (data.status) {
                        var stores = data.stores;
                        return stores;
                    }
                });
            }
        };
    });
}());
<body ng-app="globalApp">
  <section>	
    <div ng-controller="IndexController">
       <nav>
        <a ng-repeat="store in stores" href="<%store.link%>"><%store.name%></a>
      </nav>
    </div>
  </section>
  <footer>
    <div>
        <ul ng-controller="StoreListController">
            <li ng-repeat="store in stores">
                <h3><a href="<%store.link%>"><%store.name%></a></h3>
                <p>
                    <%store.street%>, <%store.number%>
                    <%store.neighborhood%>, <%store.cityName%>
                    <a><%store.phone%></a>
                    <a><%store.email%></a>
                </p>
            </li>
        </ul>
    </div>
   </footer>
</body>

如果两个控制器同时加载并调用函数,存储区将不包含任何数据,因此其长度将计算为0。

如果您需要在页面的加载时执行此操作,为什么不从服务调用函数并存储结果呢。您可以在控件中使用observer模式来侦听对集合的更改,并在promise解析后将这些更改保留到两个控制器以设置$scope.stores的值。

我的解决方案:

(function () {
    'use strict';
    // My configs (optional)
    var app = angular.module('globalApp', []).config([
        '$interpolateProvider', '$httpProvider',
        function ($interpolateProvider, $httpProvider) {
            delete $httpProvider.defaults.headers.common['X-Requested-With'];
            $interpolateProvider.startSymbol('<%');
            $interpolateProvider.endSymbol('%>');
        }
    ]);
    // Index Store List
    app.controller('IndexController', [
        '$scope', '$storeList', 'StoreService',
        function ($scope, $storeList, StoreService) {
            $scope.stores = [];
            $storeList.getStoreList().then(function (stores) {
                $scope.stores = stores;
                StoreService.setStores(stores);
            });
        }]);
  
    // Footer Store List
    app.controller('StoreListController', [
        '$scope', 'StoreService',
        function ($scope, StoreService) {
            $scope.stores = [];
            $scope.$watch(function () {
                return StoreService.getStores();
            }, function (stores) {
                $scope.stores = stores;
            }, true);
        }
    ]);
  
    // StoreService to share vars between the controllers
    app.service('StoreService', function () {
        var stores = [];
        return {
            setStores: function (_stores) {
                stores = _stores;
            },
            getStores: function () {
                return stores;
            }
        };
    });
  
    // Factory make ajax call to get list of stores
    app.factory('$storeList', function ($http) {
        return {
            getStoreList: function () {
                var uri = rootUrl + 'getStoreList';
                var responsePromise = $http.get(uri);
                return responsePromise.then(function (result) {
                    var data = result.data;
                    if (data.status) {
                        return data.stores;
                    }
                    return [];
                });
            }
        };
    });
  
}());
<body ng-app="globalApp">
  <section>	
    <div ng-controller="IndexController">
       <nav>
        <a ng-repeat="store in stores" href="<%store.link%>"><%store.name%></a>
      </nav>
    </div>
  </section>
  <footer>
    <div>
        <ul ng-controller="StoreListController">
            <li ng-repeat="store in stores">
                <h3><a href="<%store.link%>"><%store.name%></a></h3>
                <p>
                    <%store.street%>, <%store.number%>
                    <%store.neighborhood%>, <%store.cityName%>
                    <a><%store.phone%></a>
                    <a><%store.email%></a>
                </p>
            </li>
        </ul>
    </div>
   </footer>
</body>

这里不需要defer。删除此区块:

          //is a request needed?
            if (stores.length > 0) {
                var deferred = $q.defer();
                deferred.resolve(stores);
                return deferred.promise;
            }

您的IndexControllerStoreListController都在加载存储列表,因此有2个AJAX调用。从2个控制器中的任何一个移除区块

        $scope.stores = [];
        $storeList.getStoreList().then(function (stores) {
            $scope.stores = stores;
        });

编辑

我之前没有意识到,但由于您在StoreController的范围之外使用storeList,您应该仅从StoreController 中删除.getStoreList()调用