Spec-Zone.ru › Angular.js 1.8

Улучшить эту документацию Просмотреть исходный код $resource

  1. $resourceProvider
  2. сервис в модуле ngResource

Обзор

Фабрика, которая создаёт объект ресурса, позволяющий взаимодействовать с RESTful источниками данных на стороне сервера.

Возвращаемый объект ресурса имеет методы действий, которые предоставляют высокоуровневое поведение без необходимости взаимодействия с низкоуровневым сервисом $http.

Требуется модуль ngResource для установки.

По умолчанию, конечные слэши будут удаляться из вычисленных URL, что может вызвать проблемы с серверными бэкендами, которые не ожидают такого поведения. Это можно отключить, настроив $resourceProvider следующим образом:

app.config(['$resourceProvider', function($resourceProvider) {
  // Don't strip trailing slashes from calculated URLs
  $resourceProvider.defaults.stripTrailingSlashes = false;
}]);

Зависимости

  • $http
  • $log
  • $q
  • $timeout

Использование

$resource(url, [paramDefaults], [actions], options);

Аргументы

Параметр Тип Подробности
url string

Шаблон параметризованного URL с параметрами, заданными префиксом : как в /user/:username. Если вы используете URL с номером порта (например, http://example.com:8080/api), он будет учтён.

Если вы используете URL с суффиксом, просто добавьте суффикс, например: $resource('http://example.com/resource.json') или $resource('http://example.com/:id.json') или даже $resource('http://example.com/resource/:resource_id.:format'). Если параметр перед суффиксом пустой, :resource_id в данном случае, тогда /. будет сведен к одному .. Если вам нужно, чтобы эта последовательность отображалась и не сводилась, вы можете экранировать её /\..

paramDefaults
(необязательно)
Object

Значения по умолчанию для url параметров. Их можно переопределить в методах actions. Если значение параметра является функцией, она будет вызываться каждый раз, когда нужно получить значение параметра для запроса (если параметр не был переопределён). Функция получит текущее значение данных в качестве аргумента.

Каждое значение ключа в объекте параметра сначала привязывается к шаблону URL, если он присутствует, а затем все лишние ключи добавляются к поисковой строке URL после ?.

Учитывая шаблон /path/:verb и параметр {verb: 'greet', salutation: 'Hello'} приводит к URL /path/greet?salutation=Hello.

Если значение параметра имеет префикс @, то значение для этого параметра будет извлечено из соответствующего свойства объекта data (предоставленного при вызове действий с телом запроса). Например, если объект defaultParam равен {someParam: '@someProp'}, то значение someParam будет data.someProp. Обратите внимание, что параметр будет пропущен при вызове метода действия "GET" (то есть метода действия, не принимающего тело запроса).

actions
(необязательно)
Object.<Object>=

Хеш с объявлением пользовательских действий, которые будут доступны в дополнение к набору стандартных действий ресурса (см. ниже). Если пользовательское действие имеет тот же ключ, что и стандартное действие (например, save), стандартное действие будет перезаписано, а не расширено.

Объявление должно быть создано в формате $http.config:

{
  action1: {method:?, params:?, isArray:?, headers:?, ...},
  action2: {method:?, params:?, isArray:?, headers:?, ...},
  ...
}

Где:

  • action – {строка} – Имя действия. Это имя становится именем метода в вашем объекте ресурса.
  • method – {строка} – Регистронезависимый HTTP-метод (например, GET, POST, PUT, DELETE, JSONP, и т.д.).
  • params – {Объект=} – Необязательный набор предварительно привязанных параметров для этого действия. Если значение параметра является функцией, она будет вызываться каждый раз, когда нужно получить значение параметра для запроса (если параметр не был переопределён). Функция получит текущее значение данных в качестве аргумента.
  • url – {строка} – Специфичный для действия переопределение url. Шаблонизация URL поддерживается так же, как и для URL-адресов ресурса.
  • isArray – {логическое значение=} – Если true, то возвращаемый объект для этого действия представляет собой массив, см. раздел returns.
  • transformRequest – {function(data, headersGetter)|Array.<function(data, headersGetter)>} – Функция преобразования или массив таких функций. Функция преобразования принимает тело и заголовки HTTP-запроса и возвращает его преобразованную (обычно сериализованную) версию. По умолчанию, transformRequest будет содержать одну функцию, которая проверяет, является ли данные запроса объектом, и сериализует его с помощью angular.toJson. Чтобы предотвратить это поведение, установите transformRequest в пустой массив: transformRequest: []
  • transformResponse – {function(data, headersGetter, status)|Array.<function(data, headersGetter, status)>} – Функция преобразования или массив таких функций. Функция преобразования принимает тело, заголовки и статус HTTP-ответа и возвращает его преобразованную (обычно десериализованную) версию. По умолчанию, transformResponse будет содержать одну функцию, которая проверяет, похож ли ответ на строку JSON, и десериализует её с помощью angular.fromJson. Чтобы предотвратить это поведение, установите transformResponse в пустой массив: transformResponse: []
  • cache – {boolean|Cache} – Логическое значение или объект, созданный с помощью $cacheFactory для включения или отключения кэширования HTTP-ответа. См. $http Кэширование для получения дополнительной информации.
  • timeout – {number} – Таймаут в миллисекундах.
    Примечание: В отличие от $http.config, обещания не поддерживаются в $resource, поскольку одно и то же значение будет использоваться для нескольких запросов. Если вам нужен способ отмены запросов, используйте параметр cancellable.
  • cancellable – {boolean} – Если true, запрос, сделанный вызовом "не-экземпляра", будет отменён (если ещё не завершён) путём вызова $cancelRequest() на возвращаемом значении вызова. Вызов $cancelRequest() для неотменяемого или уже завершённого/отменённого запроса не окажет никакого влияния.
  • withCredentials – {boolean} – Нужно ли установить флаг withCredentials в объекте XHR. См. XMLHttpRequest.withCredentials для получения дополнительной информации.
  • responseType – {string} – См. XMLHttpRequest.responseType.
  • interceptor – {Object=} – Объект-перехватчик имеет четыре необязательных метода - request, requestError, response, и responseError. См. $http перехватыватели для получения подробностей. Обратите внимание, что перехватыватели request/requestError применяются до вызова $http, следовательно, перед любыми глобальными перехватывателями $http. Кроме того, отказ или возникновение ошибки внутри перехватывателя request приведёт к вызову перехватывателя responseError . Экземпляр ресурса или коллекции доступен по свойству resource объекта http response переданного в перехватыватели response/responseError . Имейте в виду, что связанное обещание будет разрешено значением, возвращенным перехватывателями ответа. Убедитесь, что вы возвращаете соответствующее значение, а не объект response , переданный в качестве входного значения. Для справки, перехватчик по умолчанию response (который применяется, если вы не указываете пользовательский) возвращает response.resource.
    См. ниже для примера использования перехватывателей в $resource.
  • hasBody – {boolean} – Если true, запрос будет иметь тело. Если не указано, то только POST, PUT и PATCH запросы будут иметь тело. *
options Object

Хеш с пользовательскими настройками, которые должны расширить поведение по умолчанию $resourceProvider. Поддерживаемые параметры:

  • stripTrailingSlashes – {логическое значение} – Если true, то конечные слэши из любого вычисленного URL будут удалены. (По умолчанию true.)
  • cancellable – {логическое значение} – Если true, запрос, сделанный вызовом "не-экземпляра", будет отменён (если ещё не завершён) путём вызова $cancelRequest() на возвращаемом значении вызова. Это можно переопределить для каждого действия. (По умолчанию false.)

Возвращает

Object

Объект ресурса "класса" с методами для набора стандартных действий с ресурсами, которые дополнительно могут быть расширены пользовательскими actions. Стандартный набор включает следующие действия:

{
  'get':    {method: 'GET'},
  'save':   {method: 'POST'},
  'query':  {method: 'GET', isArray: true},
  'remove': {method: 'DELETE'},
  'delete': {method: 'DELETE'}
}

Вызов этих методов вызывает $http с указанным HTTP-методом, целевым адресом и параметрами. Когда данные возвращаются сервером, объект становится экземпляром класса ресурса. Действия save, remove и delete доступны в виде методов с префиксом $. Это позволяет легко выполнять операции CRUD (создание, чтение, обновление, удаление) с данными на стороне сервера, например так:

var User = $resource('/user/:userId', {userId: '@id'});
User.get({userId: 123}).$promise.then(function(user) {
  user.abc = true;
  user.$save();
});

Важно понимать, что вызов метода объекта $resource немедленно возвращает пустую ссылку (объект или массив в зависимости от isArray). После возвращения данных с сервера существующая ссылка заполняется фактическими данными. Это полезный трюк, поскольку обычно ресурс присваивается модели, которая затем отображается представлением. Наличие пустого объекта не приводит к отображению, после получения данных с сервера объект заполняется данными, и представление автоматически перерисовывается, показывая новые данные. Это означает, что в большинстве случаев вам не нужно писать функцию обратного вызова для методов действий.

Методы действий для объекта класса или экземпляра объекта могут вызываться со следующими параметрами:

  • "Действия класса" без тела: Resource.action([parameters], [success], [error])
  • "Действия класса" с телом: Resource.action([parameters], postData, [success], [error])
  • Действия экземпляра: instance.$action([parameters], [success], [error])

При вызове методов экземпляра сам экземпляр используется в качестве тела запроса (если действие должно иметь тело). По умолчанию тела запроса имеют только действия, использующие POST, PUT или PATCH, но вы можете использовать параметр конфигурации hasBody, чтобы указать, должно ли действие иметь тело или нет (независимо от HTTP-метода).

Обратный вызов успеха вызывается с аргументами (значение (Объект|Массив), заголовки ответа (Функция), статус (число), текст статуса (строка)), где value — это заполненный экземпляр или коллекция ресурса. Обратный вызов ошибки вызывается с аргументом (httpResponse).

Действия класса возвращают пустой экземпляр (с дополнительными свойствами, перечисленными ниже). Действия экземпляра возвращают промис для операции.

Экземпляры и коллекции ресурсов имеют следующие дополнительные свойства:

  • $promise: Промис исходного взаимодействия с сервером, которое создало этот экземпляр или коллекцию.

    При успехе промис разрешается с тем же экземпляром или коллекцией ресурса, обновлённым данными с сервера. Это упрощает использование в resolve разделе $routeProvider.when() для отложенного рендеринга представления до загрузки ресурса(ов).

    При ошибке промис отклоняется с объектом ответа HTTP.

    Если был предоставлен объект-интерцептор, промис вместо этого разрешается значением, возвращённым интерцептором ответа (при успехе) или интерцептором ошибки ответа (при ошибке).

  • $resolved: true после завершения первого взаимодействия с сервером (будь то успех или отклонение), false до этого. Знание того, был ли ресурс разрешён, полезно при привязке данных. Если есть интерцептор ответа/ответError и он возвращает промис, $resolved будет ожидать этого тоже.

    Экземпляры и коллекции ресурсов имеют следующие дополнительные методы:

  • $cancelRequest: Если существует отменяемый, ожидающий запрос, связанный с экземпляром или коллекцией, вызов этого метода прервёт запрос.

    Экземпляры ресурсов имеют следующие дополнительные методы:

  • toJSON: Возвращает простой объект без дополнительных свойств, добавленных в API ресурса. Этот объект можно сериализовать с помощью angular.toJson безопасно без прикрепления специфичных для AngularJS полей. Обратите внимание, что JSON.stringify (и angular.toJson) автоматически используют этот метод при сериализации экземпляра ресурса (см. MDN).

Примеры

Базовое использование

// Define a CreditCard class
var CreditCard = $resource('/users/:userId/cards/:cardId',
  {userId: 123, cardId: '@id'}, {
    charge: {method: 'POST', params: {charge: true}}
  });

// We can retrieve a collection from the server
var cards = CreditCard.query();
    // GET: /users/123/cards
    // server returns: [{id: 456, number: '1234', name: 'Smith'}]

// Wait for the request to complete
cards.$promise.then(function() {
  var card = cards[0];

  // Each item is an instance of CreditCard
  expect(card instanceof CreditCard).toEqual(true);

  // Non-GET methods are mapped onto the instances
  card.name = 'J. Smith';
  card.$save();
      // POST: /users/123/cards/456 {id: 456, number: '1234', name: 'J. Smith'}
      // server returns: {id: 456, number: '1234', name: 'J. Smith'}

  // Our custom method is mapped as well (since it uses POST)
  card.$charge({amount: 9.99});
      // POST: /users/123/cards/456?amount=9.99&charge=true {id: 456, number: '1234', name: 'J. Smith'}
});

// We can create an instance as well
var newCard = new CreditCard({number: '0123'});
newCard.name = 'Mike Smith';

var savePromise = newCard.$save();
    // POST: /users/123/cards {number: '0123', name: 'Mike Smith'}
    // server returns: {id: 789, number: '0123', name: 'Mike Smith'}

savePromise.then(function() {
  // Once the promise is resolved, the created instance
  // is populated with the data returned by the server
  expect(newCard.id).toEqual(789);
});

Объект, возвращаемый при вызове $resource, — это ресурс "класса", у которого есть один "статический" метод для каждого действия в определении.

Вызов этих методов вызывает $http на шаблоне url с заданным HTTP-методом method, params и headers.

Доступ к ответу

Когда данные возвращаются сервером, объект становится экземпляром типа ресурса, и все методы, кроме GET, доступны с префиксом $. Это позволяет легко поддерживать операции CRUD (создание, чтение, обновление, удаление) с данными на стороне сервера.

var User = $resource('/users/:userId', {userId: '@id'});
User.get({userId: 123}).$promise.then(function(user) {
  user.abc = true;
  user.$save();
});

Стоит отметить, что обратный вызов успеха для get, query и других методов вызывается с экземпляром ресурса (заполненным данными, полученными с сервера), а также с функцией-получателем заголовков $http, кодом HTTP-статуса и текстом статуса ответа. Таким образом, можно переписать вышеприведённый пример и получить доступ к заголовкам HTTP следующим образом:

var User = $resource('/users/:userId', {userId: '@id'});
User.get({userId: 123}, function(user, getResponseHeaders) {
  user.abc = true;
  user.$save(function(user, putResponseHeaders) {
    // `user` => saved `User` object
    // `putResponseHeaders` => `$http` header getter
  });
});

Создание пользовательских действий

В этом примере мы создаём пользовательский метод для нашего ресурса для выполнения запроса PUT:

var app = angular.module('app', ['ngResource']);

// Some APIs expect a PUT request in the format URL/object/ID
// Here we are creating an 'update' method
app.factory('Notes', ['$resource', function($resource) {
  return $resource('/notes/:id', {id: '@id'}, {
    update: {method: 'PUT'}
  });
}]);

// In our controller we get the ID from the URL using `$location`
app.controller('NotesCtrl', ['$location', 'Notes', function($location, Notes) {
  // First, retrieve the corresponding `Note` object from the server
  // (Assuming a URL of the form `.../notes?id=XYZ`)
  var noteId = $location.search().id;
  var note = Notes.get({id: noteId});

  note.$promise.then(function() {
    note.content = 'Hello, world!';

    // Now call `update` to save the changes on the server
    Notes.update(note);
        // This will PUT /notes/ID with the note object as the request payload

    // Since `update` is a non-GET method, it will also be available on the instance
    // (prefixed with `$`), so we could replace the `Note.update()` call with:
    //note.$update();
  });
}]);

Отмена запросов

Если конфигурация действия указывает, что оно отменяемо, вы можете отменить запрос, связанный с экземпляром или коллекцией (если это результат вызова "не экземпляра"):

// ...defining the `Hotel` resource...
var Hotel = $resource('/api/hotels/:id', {id: '@id'}, {
  // Let's make the `query()` method cancellable
  query: {method: 'get', isArray: true, cancellable: true}
});

// ...somewhere in the PlanVacationController...
...
this.onDestinationChanged = function onDestinationChanged(destination) {
  // We don't care about any pending request for hotels
  // in a different destination any more
  if (this.availableHotels) {
    this.availableHotels.$cancelRequest();
  }

  // Let's query for hotels in `destination`
  // (calls: /api/hotels?location=<destination>)
  this.availableHotels = Hotel.query({location: destination});
};

Использование интерцепторов

Вы можете использовать интерцепторы для преобразования запроса или ответа, выполнения дополнительных операций и изменения возвращаемого экземпляра/коллекции. В следующем примере используются интерцепторы request и response для дополнения возвращаемого экземпляра дополнительной информацией:

var Thing = $resource('/api/things/:id', {id: '@id'}, {
  save: {
    method: 'POST',
    interceptor: {
      request: function(config) {
        // Before the request is sent out, store a timestamp on the request config
        config.requestTimestamp = Date.now();
        return config;
      },
      response: function(response) {
        // Get the instance from the response object
        var instance = response.resource;

        // Augment the instance with a custom `saveLatency` property, computed as the time
        // between sending the request and receiving the response.
        instance.saveLatency = Date.now() - response.config.requestTimestamp;

        // Return the instance
        return instance;
      }
    }
  }
});

Thing.save({foo: 'bar'}).$promise.then(function(thing) {
  console.log('That thing was saved in ' + thing.saveLatency + 'ms.');
});

© 2010–2020 Google, Inc.
Licensed under the Creative Commons Attribution License 3.0.
https://code.angularjs.org/1.8.2/docs/api/ngResource/service/$resource

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API