Spec-Zone.ru › Angular.js 1.7

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

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

Обзор

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

Возвращаемый объект ресурса имеет методы действий, которые обеспечивают высокоуровневое поведение без необходимости взаимодействия с низкоуровневым сервисом $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 – {string} – Название действия. Это имя становится именем метода в вашем объекте ресурса.
  • method – {string} – Регистронезависимый HTTP-метод (например, GET, POST, PUT, DELETE, JSONP, и т.д.).
  • params – {Object=} – Необязательный набор предварительно связанных параметров для этого действия. Если какое-либо значение параметра является функцией, оно будет вызываться каждый раз, когда требуется получить значение параметра для запроса (если параметр не был переопределён). Функция получит текущее значение данных в качестве аргумента.
  • url – {string} – Специфичное для действия переопределение url. Шаблонизация URL поддерживается так же, как и для URL на уровне ресурса.
  • isArray – {boolean=} – Если 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 – {boolean} – Если true, то конечные слэши из любого рассчитанного URL-адреса будут удалены. (По умолчанию true.)
  • cancellable – {boolean} – Если 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–2018 Google, Inc.
Licensed under the Creative Commons Attribution License 4.0.
https://code.angularjs.org/1.7.8/docs/api/ngResource/service/$resource

Spec-Zone.ru

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