Настройка: я хочу иметь службу, которую несколько контроллеров могут запрашивать для получения данных, используя $http. Первоначальное решение заключалось в использовании промисов, как было предложено здесь.
Проблема: каждый раз, когда контроллер запрашивает службу, служба затем возвращает обещание $http, что приводит к нескольким запросам, которые снова и снова извлекают одни и те же данные с удаленного сервера.
Решение. Сервисная функция возвращает либо данные, либо обещание, как показано ниже. И это зависит от контроллера, чтобы проверить и действовать соответственно.
app.factory('myService', function($http) {
var items = [];
var myService = {
getItems: function() {
// if items has content, return items; otherwise, return promise.
if (items.length > 0) {
return items;
} else {
var promise = $http.get('test.json').then(function (response) {
// fill up items with result, so next query just returns items.
for(var i=0;i<response.data.length;i++){
items.push(response.data[i]);
}
return items;
});
// Return the promise to the controller
return promise;
}
};
return myService;
});
Поэтому, когда контроллеру нужны эти данные, контроллер просто делает что-то вроде этого:
app.controller('MainCtrl', function( myService,$scope) {
var promiseOrData = myService.async();
// Check whether result is a promise or data.
if ( typeof promiseOrData.then === 'function'){
// It's a promise. Use then().
promiseOrData.then( function(data ){
$scope.data = data;
});
} else {
// It's data.
$scope.data = data;
}
});
Вопрос в следующем: есть ли лучший способ сделать это? Со многими контроллерами этот метод будет иметь много повторяющегося кода. В идеале контроллеры будут просто напрямую запрашивать данные у службы.
Спасибо!