#angularjs #angular-ui-router #angular-resource
#angularjs #angular-пользовательский интерфейс-маршрутизатор #angular-ресурс
Вопрос:
Я запускаю пользовательский интерфейс-маршрутизатор с разрешением в нем, и разрешенные данные выглядят следующим образом:
myService: "myService"
items: function(myService){
var promise = myService.resource.query().$promise;
return promise;
}
Однако, если это обещание не выполняется, все состояние прерывается и генерируется $stateChangeError. Я хочу вместо того, чтобы прерывать все состояние, просто установить значение элементов в качестве значения по умолчанию и перейти к состоянию. Единственное решение, которое я смог найти, похоже на взлом:
myService: "myService",
items: ['myService', '$q', function(myService, $q) {
//return []
defObj = $q.defer();
var promise = myService.resource.query().$promise;
promise.then(function(data) {
defObj.resolve(data);
},function(error) {
defObj.resolve([{title: "sorry, could not load"}]);
})
return defObj.promise;
}]
При этом, независимо от того, будет ли запрос выполнен с ошибкой, обещание будет выполнено, и состояние будет продолжено. Есть ли какие-нибудь более простые решения этой проблемы?
Если это имеет значение, я использую это в рамках решения, потому что информация влияет на поток страницы, и я не хочу, чтобы она загружала страницу до тех пор, пока не будут загружены данные
Ответ №1:
Упрощенная проблема :
myService: "myService"
items: function(myService){
return myService.resource.query();
}
Решение :
myService: "myService"
items: function(myService){
return myService.resource.query()
.then(function(data) {
return data;
}, function() {
return [{title: "sorry, could not load"}];
});
}
Редактировать:
Приведенный выше код предназначен для простого вызова службы, возвращающего обещание.
Для API $ressource:
из этого примера кода из документации :
User.get({userId:123})
.$promise.then(function(user) {
$scope.user = user;
});
Я думаю, вы могли бы упростить это :
myService: "myService",
items: ['myService', function(myService) {
return myService.resource.query().$promise
.then(function(data) {
return data;
},function(error) {
return [{title: "sorry, could not load"}];
});
}]
И нет, нехорошо заключать обещание в отложенный сервис ( $q
). За исключением случаев, когда у вас есть несколько обещаний.
Комментарии:
1. Я считаю, что использование $promise является обязательным. Как и в случае с решением работать должным образом в маршрутизаторе, ему должно быть передано $promise, а не только действие ресурса
2. jvandemo.com/how-to-resolve-angularjs-resources-with-ui-router для объяснения того, почему $promise необходимо
3. Я думал, что query — это сервис, который вы написали, а не angular ressource API
4. В этом примере используется обычное обещание, вызывающее пользовательскую службу. Я не вижу проблем в вашем коде. Если это работает с вашим API
5. Когда вы говорите «мой код», вы имеете в виду второй фрагмент кода? Как вы думаете, окружение вызова ресурса (внутри которого есть $ q) другим $ q стилистически нормально?
Ответ №2:
Наконец-то решил это…. Ключ добавляет перехватчик с функцией responseError в определение метода ресурса
"query": {
method: "GET",
isArray: true,
/*This will prevent the promise from being rejected even on fail*/
interceptor: {
responseError: function() {
return [{title: "Sorry, could not load"}];
}
}
}