Вызов службы из Restangular ResponseInterceptor (ResponseExtractor)

Я пытаюсь расширить поле внешнего ключа для элемента, который я получаю из своей серверной службы после добавления элемента в коллекцию, используя Restangular.

Служба отвечает на мой POST элементом, включая поле url, ссылающееся на связанный объект, и у меня уже есть служба для этих объектов.

Ответ выглядит так:

{
    "url": "http://api.example.com/resources/6/", 
    "name": "Harry", 
    "role": "http://api.example.com/roles/1/", 
}

и я хотел бы расширить поле role до чего-то вроде:

{
    "url": "http://api.example.com/resources/6/", 
    "name": "Harry", 
    "role": "Administrator", 
}

пока имею следующее:

Configurer.setResponseInterceptor(function(data, operation, what, url, response, deferred) {
    if ((operation == 'post' || operation == 'put') && what == 'resources' && 'role' in data && data.role.substr(0,4) == 'http') {
        console.log('Role URL instead of name -- change this');
    }
    return data;
});

и в идеале я хотел бы назвать мою существующую службу, которая обертывает Restangular; нужен инжектор? Или есть лучший способ?


person mkornblum    schedule 05.11.2013    source источник
comment
В качестве альтернативы и с большей пользой я бы хотел, чтобы поле role было расширено до полного объекта роли, чтобы я мог использовать разрешения и т. д.   -  person mkornblum    schedule 05.11.2013


Ответы (2)


Между прочим, цель исходного вопроса возможна.

«Вызов службы из Restangular ResponseInterceptor»

пример:

angular.module('app').factory('myApi', [
  'Restangular', 'myService', '$rootScope', function(restangular, myService, $rootScope) {
    return restangular.withConfig(function(c) {
      c.setResponseInterceptor(function(data, op, what, url, response, deferred) {
        if (op === 'post' && what === 'the_name_of_some_resource' && url.match(/something_or_other/)) {
          myService.doSomething(response.data.something_cool);
          $rootScope.$emit('didSomethingCool');
        }
        return response.data;
      });
    });
  }
]);

Затем просто введите myApi и используйте его вместо Restangular. Перехватчик ответа имеет доступ к myService. Обратите внимание, это не лучший дизайн (сложно протестировать), но что-то в этом роде мне пригодилось, чтобы отложить необходимость рефакторинга кучи разбросанного кода, который напрямую вызывал реугольный метод, поэтому я подумал, что я поделился бы здесь. Вместо рефакторинга всех прямых вызовов restangular в службу (лучший дизайн), это был способ связать запросы/ответы некоторой активности API, которая вызывается в нескольких местах и ​​внезапно нуждалась в изменении некоторого состояния всякий раз, когда ответ был получен. .

Часть $rootScope не важна для вопроса OP, я включил ее, чтобы проиллюстрировать, что вы можете вводить произвольные вещи (не провайдеры) в фабрику, которая поставляет restangular с измененной конфигурацией; это, конечно, включает в себя ваши собственные экземпляры службы, которые затем могут быть вызваны из перехватчика ответа.

Еще одно примечание: setResponseInterceptor устарел, и его преемник addResponseInterceptor имеет другую подпись (я думаю)

Ничего из этого не проверялось, и я не проверял свои факты.

person Blake Miller    schedule 29.03.2014

Проверьте этот пост:

http://ath3nd.wordpress.com/2013/08/05/15/

Есть пример именно этого: увеличение возврата сервером.

Поскольку Restangular возвращает промис, чтобы сохранить этот поток, вам также придется возвращать промис в своем сервисе, для чего вам придется внедрить сервис $q.

person Nikola Yovchev    schedule 05.11.2013
comment
Ах хорошо. На данный момент у меня немного гибридный подход, который, как следует из статьи, я должен изменить; У меня есть дополнительные методы, добавленные в мою коллекцию Restangular с помощью метода addElementTransformer, и они отвечают за POST, в основном обходя созданную мной службу; отсюда мое использование ResponseInterceptor. Знаете ли вы, есть ли способ Restangular для доступа к другому объекту Restangular из перехватчика? Или мне нужно сделать рефакторинг? - person mkornblum; 05.11.2013
comment
Как автор статьи, я бы посоветовал вам провести рефакторинг, даже если есть способ сделать то, что вы хотите сделать. Простота имеет большое значение для меня. - person Nikola Yovchev; 05.11.2013