$resource resolve в пользовательском интерфейсе -перехват ошибок маршрутизатора не приводит к сбою состояния

#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"}];
                }
            }

        }