Я работаю над приложением для серии видео, которое настроено так:
angular.module('videoSeries', ['ngAnimate', 'ui.router'])
.config(config)
.factory('episodes', episodesFactory)
.controller('MainCtrl', MainCtrl)
.controller('EpisodeCtrl', EpisodeCtrl);
Фабричные «эпизоды» загружают файл JSONP, из которого оба контроллера должны читать. Чтобы контроллеры дождались успешного возврата JSONP, я установил обещание на фабрике следующим образом (как предложено здесь):
episodesFactory.$inject = ['$http', '$q'];
function episodesFactory($http, $q) {
var pub = {},
jsonUrl = 'http://i.cdn.turner.com/nba/nba/.element/media/2.0/teamsites/warriors/json/json-wgtv.js?callback=JSON_CALLBACK' + (new Date().getTime()),
cachedResponse;
pub.getData = function() {
var deferred = $q.defer();
if (cachedResponse) {
deferred.resolve(cachedResponse);
}
else {
$http.jsonp(jsonUrl);
window.jsonCallbackWGTV = function(data) {
cachedResponse = data;
deferred.resolve(data);
}
}
return deferred.promise;
}
return pub;
}
И затем оба контроллера выполняются после возврата .then следующим образом:
MainCtrl.$inject = ['$scope', 'episodes'];
function MainCtrl($scope, episodes) {
episodes.getData().then(function(data) {
$scope.episodes = data.episodes;
});
}
EpisodeCtrl.$inject = ['$scope', '$stateParams', 'episodes'];
function EpisodeCtrl($scope, $stateParams, episodes) {
episodes.getData().then(function(data) {
$scope.episode = data.episodes[$stateParams.episodeIndex];
});
}
Это отлично работает, если только один контроллер вызывает .getData() за раз, но если оба вызывают его одновременно (что происходит, если вы загружаетесь непосредственно в состояние эпизодов), похоже, что одно обещание забыто.
Это планкер. Обратите внимание, что для того, чтобы увидеть проблему, вы нажимаете на эпизод, а затем перезагружаетесь прямо на этот маршрут, но я не уверен, как это сделать в планкерах, поскольку URL-адрес не обновляется.