AngularJS: $ресурс с вложенными ресурсами

Я использую модель ресурсов AngularJS $для API REST. У меня есть что-то вроде этого:

angular.module('libraryapp')
    .factory('Book', function($resource){
        return $resource('books/:id');
    });

Я использую следующим образом:

Book.get({ id: 42 }, function(book) {
    console.log(book);
});

Но я также хочу, чтобы конечная точка была в subresource, скажем:

GET /books/:id/comments

Как мне определить его в модуле? Могу ли я каким-то образом расширить книгу, чтобы использовать ее так:

Book.get({ id: 42 }).Comment.query(function(comments) {
    console.log(comments);
});

Ответ 1

Вы можете легко получить вложенные ресурсы RESTful с помощью определений AngularJS $resource.

Ключ должен понять, как работает параметр params для каждого определения действия (в списке actions) в $resource. Как говорится в документации, это

Дополнительный набор предварительно привязанных параметров для этого действия. [...]

angular.module('libraryApp').factory('Book', [
  '$resource', function($resource) {
    return $resource('books/:id/:subResource', {}, {
      comments: {  // The `comments` action definition:
        params: {subResource: 'comments'},
        method: 'GET'
      }
    });
  }
]);

Учитывая приведенное выше определение, вы все равно должны использовать Book, как и раньше. Например, Book.get({ id: 42 }) переводит на запрос GET books/42/.

Однако, учитывая новую :subResource часть URL $resource ('books/:id/:subResource'), теперь вы можете сгенерировать

GET books/42/comments

вызывая либо Book.get({ id: 42, subResource: 'comments' }), либо гораздо более короткий и элегантный интерфейс Book.comments({ id: 42 }), определенный как действие comments.

Ответ 2

Насколько я знаю, вы не можете вложить ресурсы, но это довольно просто сделать, что вы ищете:

Вы можете определить необязательные параметры, которые вы можете переопределить в каждом ресурсе (например, category здесь) или даже переопределить URL-адрес (посмотрите ресурс otherUrl)

angular.module('libraryApp').factory('Book', [
  '$resource', function($resource) {
    return $resource('books/:id/:category', {}, {
      comments: {
        method: 'GET',
        action: 'category'
      },
      otherUrls: {
        method: 'GET',
        url: 'books/:id/admin/:option'
      }
    });
  }
]);

Ответ 3

Вместо этого вы можете использовать Restangular, поскольку он управляет вложенными ресурсами и чистым и простым способом.