如何避免两个相同的$http.get请求 在angularJS中,通过一个调用,当获取服务响应时,需要在多个控制器中但在同一页面中访问该json值

如何避免两个相同的$http.get请求 在angularJS中,通过一个调用,当获取服务响应时,需要在多个控制器中但在同一页面中访问该json值,angularjs,Angularjs,我有两个控制器js文件,当我在第一个controller.js中调用服务“this.getNavigationMenuDetails”时,两个控制器在同一页面中被调用,在controller2.js文件中也被调用。如果没有timeout函数,我想访问从controller2.js中的“this.getNavigationMenuDetails”服务获得的相同响应。但碰巧服务呼叫在页面中出现了两次。我不想在一个页面中调用同一服务两次。 当js加载时,在同一层中调用两个控制器,然后从服务获取响应,因

我有两个控制器js文件,当我在第一个controller.js中调用服务“this.getNavigationMenuDetails”时,两个控制器在同一页面中被调用,在controller2.js文件中也被调用。如果没有timeout函数,我想访问从controller2.js中的“this.getNavigationMenuDetails”服务获得的相同响应。但碰巧服务呼叫在页面中出现了两次。我不想在一个页面中调用同一服务两次。 当js加载时,在同一层中调用两个控制器,然后从服务获取响应,因此第二个controller2.js文件代码不会在响应后执行。我如何解决这个问题,以便只有一次调用我才能获得响应并访问controller2.js中的响应

controler1.js

var app = angular.module("navApp", []);

app.controller("navCtrl", ['$scope', 'topNavService', '$window', function ($scope, $timeout, topNavService, $window) {

    $scope.menuItemInfo = {};

    /*Navigation Menu new Code */
    $scope.getNavigationDetails = function () {
        topNavService.getNavigationMenuDetails().then(function (result) {
            $scope.menuItemInfo = result;
            angular.forEach($scope.menuItemInfo.items, function (val, key) {
                if (val.menuTitle === 
                        $window.sessionStorage.getItem('selectedNavMenu')) {
                    if ($scope.menuItemInfo.items[key].isEnabled) {
                        $scope.menuItemInfo.items[key].isActive = 'highlighted';
                    } else {
                        $window.sessionStorage.removeItem('selectedNavMenu');
                    }
                }
                if (val.menuTitle === 'Find a Fair' && !val.hasSubMenu) {
                    $scope.menuItemInfo.items[key].redirectTo = appConfig.findafairpageurl;
                }
            });
        });
    };
    $scope.init = function () {
        if ($window.location.pathname.indexOf('all-my-fairs.html') > 0) {
            if (angular.isDefined($cookies.get('cpt_bookfair'))) {
                $cookies.remove('cpt_bookfair', {
                    path: '/'
                });
            }
        }
        $scope.getNavigationDetails();
        $scope.callOnLoad();
    };

    $scope.init();
}]);
app.service('topNavService', function($http) {

  var menuInfoPromise;
  var observerList = [];
  var inProgress = false;

  this.addObserver(callback) {
    if (callback) observerList.push(callback);
  }

  this.notifyObserver() {
    observerList.forEach(callback) {
      callback();
    }
  }

  this.getNavigationMenuDetails = function() {
    if (!menuInfoPromise && !inProgress) {
      inProgress = true;
      // If menu is undefined or null populate it from the backend
      menuInfoPromise = $http.get(url);
      this.notifyObserver();
    };
    return menuInfoPromise;
  };
});
Controller2.js

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

app.controller('bookResourceCtrl', ['topNavService', '$scope', function (topNavService, $scope) {
    $scope.topInfo = '';

    topNavService.getNavigationMenuDetails.then(function success() {
        $scope.productId = $scope.topInfo.isLoggedin;
        $scope.linkParam = '?productId=' + $scope.productId;
    }, function failure() {
        console.error("something bad happened");
    });
}]);

如果该服务缓存HTTP承诺而不是值,则会更好地工作:

app.service('topNavService', function ($http) {

    var menuInfoPromise;
    this.getNavigationMenuDetails = function () {
        if (!menuInfoPromise) {
            // If menu is undefined or null populate it from the backend
            menuInfoPromise =  $http.get(url);
        };
        return menuInfoPromise;
    };

});

缓存值的错误方法引入了竞争条件。如果第二个控制器在数据从服务器到达之前调用,则服务会为数据发送第二个XHR

如果缓存HTTP承诺而不是值,则该服务会工作得更好:

app.service('topNavService', function ($http) {

    var menuInfoPromise;
    this.getNavigationMenuDetails = function () {
        if (!menuInfoPromise) {
            // If menu is undefined or null populate it from the backend
            menuInfoPromise =  $http.get(url);
        };
        return menuInfoPromise;
    };

});

缓存值的错误方法引入了竞争条件。如果第二个控制器在数据从服务器到达之前调用,则服务会为数据发送第二个XHR

您可以使用以下方法来实现这一点

Service.js

var app = angular.module("navApp", []);

app.controller("navCtrl", ['$scope', 'topNavService', '$window', function ($scope, $timeout, topNavService, $window) {

    $scope.menuItemInfo = {};

    /*Navigation Menu new Code */
    $scope.getNavigationDetails = function () {
        topNavService.getNavigationMenuDetails().then(function (result) {
            $scope.menuItemInfo = result;
            angular.forEach($scope.menuItemInfo.items, function (val, key) {
                if (val.menuTitle === 
                        $window.sessionStorage.getItem('selectedNavMenu')) {
                    if ($scope.menuItemInfo.items[key].isEnabled) {
                        $scope.menuItemInfo.items[key].isActive = 'highlighted';
                    } else {
                        $window.sessionStorage.removeItem('selectedNavMenu');
                    }
                }
                if (val.menuTitle === 'Find a Fair' && !val.hasSubMenu) {
                    $scope.menuItemInfo.items[key].redirectTo = appConfig.findafairpageurl;
                }
            });
        });
    };
    $scope.init = function () {
        if ($window.location.pathname.indexOf('all-my-fairs.html') > 0) {
            if (angular.isDefined($cookies.get('cpt_bookfair'))) {
                $cookies.remove('cpt_bookfair', {
                    path: '/'
                });
            }
        }
        $scope.getNavigationDetails();
        $scope.callOnLoad();
    };

    $scope.init();
}]);
app.service('topNavService', function($http) {

  var menuInfoPromise;
  var observerList = [];
  var inProgress = false;

  this.addObserver(callback) {
    if (callback) observerList.push(callback);
  }

  this.notifyObserver() {
    observerList.forEach(callback) {
      callback();
    }
  }

  this.getNavigationMenuDetails = function() {
    if (!menuInfoPromise && !inProgress) {
      inProgress = true;
      // If menu is undefined or null populate it from the backend
      menuInfoPromise = $http.get(url);
      this.notifyObserver();
    };
    return menuInfoPromise;
  };
});
您必须在服务中创建一个函数,才能将控制器的函数添加到列表中。然后,每个控制器将在服务上注册其get函数,并调用服务方法来获取数据。第一次调用将使进程中的服务变量
变为true。因此,它将防止出现多个服务器请求。然后,当数据可用于服务时,它将调用其
notifyObserver
函数,通过调用它们的函数为所有控制器发送消息

控制器1

app.controller('ctrl1', ['service', '$scope', function(service, $scope) {
  service.addObserver('getData1'); //name of your controller function

  $scope.getData1() {
    service.getNavigationMenuDetails.then(function success() {
      $scope.productId = $scope.topInfo.isLoggedin;
      $scope.linkParam = '?productId=' + $scope.productId;
    }, function failure() {
      console.error("something bad happened");
    });
  }
  $scope.getData1()
}]);
控制器2

app.controller('ctrl1', ['service', '$scope', function(service, $scope) {
  service.addObserver('getData2'); //name of your controller function

  $scope.getData2() {
    service.getNavigationMenuDetails.then(function success() {
      $scope.productId = $scope.topInfo.isLoggedin;
      $scope.linkParam = '?productId=' + $scope.productId;
    }, function failure() {
      console.error("something bad happened");
    });
  }

  $scope.getData2()
}]);

通过这种方法,您可以将数据实时更新到不同的控制器,而无需向服务器发出多个相同的请求。

您可以通过以下方法完成此操作

Service.js

var app = angular.module("navApp", []);

app.controller("navCtrl", ['$scope', 'topNavService', '$window', function ($scope, $timeout, topNavService, $window) {

    $scope.menuItemInfo = {};

    /*Navigation Menu new Code */
    $scope.getNavigationDetails = function () {
        topNavService.getNavigationMenuDetails().then(function (result) {
            $scope.menuItemInfo = result;
            angular.forEach($scope.menuItemInfo.items, function (val, key) {
                if (val.menuTitle === 
                        $window.sessionStorage.getItem('selectedNavMenu')) {
                    if ($scope.menuItemInfo.items[key].isEnabled) {
                        $scope.menuItemInfo.items[key].isActive = 'highlighted';
                    } else {
                        $window.sessionStorage.removeItem('selectedNavMenu');
                    }
                }
                if (val.menuTitle === 'Find a Fair' && !val.hasSubMenu) {
                    $scope.menuItemInfo.items[key].redirectTo = appConfig.findafairpageurl;
                }
            });
        });
    };
    $scope.init = function () {
        if ($window.location.pathname.indexOf('all-my-fairs.html') > 0) {
            if (angular.isDefined($cookies.get('cpt_bookfair'))) {
                $cookies.remove('cpt_bookfair', {
                    path: '/'
                });
            }
        }
        $scope.getNavigationDetails();
        $scope.callOnLoad();
    };

    $scope.init();
}]);
app.service('topNavService', function($http) {

  var menuInfoPromise;
  var observerList = [];
  var inProgress = false;

  this.addObserver(callback) {
    if (callback) observerList.push(callback);
  }

  this.notifyObserver() {
    observerList.forEach(callback) {
      callback();
    }
  }

  this.getNavigationMenuDetails = function() {
    if (!menuInfoPromise && !inProgress) {
      inProgress = true;
      // If menu is undefined or null populate it from the backend
      menuInfoPromise = $http.get(url);
      this.notifyObserver();
    };
    return menuInfoPromise;
  };
});
您必须在服务中创建一个函数,才能将控制器的函数添加到列表中。然后,每个控制器将在服务上注册其get函数,并调用服务方法来获取数据。第一次调用将使进程中的服务变量
变为true。因此,它将防止出现多个服务器请求。然后,当数据可用于服务时,它将调用其
notifyObserver
函数,通过调用它们的函数为所有控制器发送消息

控制器1

app.controller('ctrl1', ['service', '$scope', function(service, $scope) {
  service.addObserver('getData1'); //name of your controller function

  $scope.getData1() {
    service.getNavigationMenuDetails.then(function success() {
      $scope.productId = $scope.topInfo.isLoggedin;
      $scope.linkParam = '?productId=' + $scope.productId;
    }, function failure() {
      console.error("something bad happened");
    });
  }
  $scope.getData1()
}]);
控制器2

app.controller('ctrl1', ['service', '$scope', function(service, $scope) {
  service.addObserver('getData2'); //name of your controller function

  $scope.getData2() {
    service.getNavigationMenuDetails.then(function success() {
      $scope.productId = $scope.topInfo.isLoggedin;
      $scope.linkParam = '?productId=' + $scope.productId;
    }, function failure() {
      console.error("something bad happened");
    });
  }

  $scope.getData2()
}]);

通过这种方法,您可以将数据实时更新到不同的控制器,而无需向服务器发出多个相同的请求。

我强烈建议,如果您和某类同行正在发布关于同一网站或作业的信息,请不要这样做。我强烈建议,如果你和同龄人正在发布关于同一个网站或作业的信息,不要这样做。