如何避免两个相同的$http.get请求 在angularJS中,通过一个调用,当获取服务响应时,需要在多个控制器中但在同一页面中访问该json值
我有两个控制器js文件,当我在第一个controller.js中调用服务“this.getNavigationMenuDetails”时,两个控制器在同一页面中被调用,在controller2.js文件中也被调用。如果没有timeout函数,我想访问从controller2.js中的“this.getNavigationMenuDetails”服务获得的相同响应。但碰巧服务呼叫在页面中出现了两次。我不想在一个页面中调用同一服务两次。 当js加载时,在同一层中调用两个控制器,然后从服务获取响应,因此第二个controller2.js文件代码不会在响应后执行。我如何解决这个问题,以便只有一次调用我才能获得响应并访问controller2.js中的响应 controler1.js如何避免两个相同的$http.get请求 在angularJS中,通过一个调用,当获取服务响应时,需要在多个控制器中但在同一页面中访问该json值,angularjs,Angularjs,我有两个控制器js文件,当我在第一个controller.js中调用服务“this.getNavigationMenuDetails”时,两个控制器在同一页面中被调用,在controller2.js文件中也被调用。如果没有timeout函数,我想访问从controller2.js中的“this.getNavigationMenuDetails”服务获得的相同响应。但碰巧服务呼叫在页面中出现了两次。我不想在一个页面中调用同一服务两次。 当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()
}]);
通过这种方法,您可以将数据实时更新到不同的控制器,而无需向服务器发出多个相同的请求。我强烈建议,如果您和某类同行正在发布关于同一网站或作业的信息,请不要这样做。我强烈建议,如果你和同龄人正在发布关于同一个网站或作业的信息,不要这样做。