Forma recomendada de obtener datos del servidor

145

¿Cuál es la forma recomendada de conectarse a las fuentes de datos del servidor en AngularJS sin usar $resource?

El $resourcetiene muchas limitaciones como:

  1. No usar futuros adecuados
  2. No ser lo suficientemente flexible
Misko Hevery
fuente
66
¿Sigue siendo cierto que $ resource tiene la limitación de no usar futuros adecuados dado que este problema (https://github.com/angular/angular.js/issues/415) se ha cerrado? (Soy nuevo en Angular, mis disculpas si la pregunta es confusa). EDITAR - ¿Esta confirmación ( github.com/angular/angular.js/commit/… ) también parece sugerir que $ resource ya no tiene esa limitación?
Jason Sydes
1
bueno, es legal aquí responder tus propias preguntas ... ¿vale? presione "Preguntar", que se llama "comparta su conocimiento"
holms

Respuestas:

229

Hay casos en que $ resource puede no ser apropiado cuando se habla con el backend. Esto muestra cómo configurar un comportamiento similar a $ resource sin usar resource.

angular.module('myApp').factory('Book', function($http) {
  // Book is a class which we can use for retrieving and 
  // updating data on the server
  var Book = function(data) {
    angular.extend(this, data);
  }

  // a static method to retrieve Book by ID
  Book.get = function(id) {
    return $http.get('/Book/' + id).then(function(response) {
      return new Book(response.data);
    });
  };

  // an instance method to create a new Book
  Book.prototype.create = function() {
    var book = this;
    return $http.post('/Book/', book).then(function(response) {
      book.id = response.data.id;
      return book;
    });
  }

  return Book;
});

Luego, dentro de su controlador puede:

var AppController = function(Book) {
  // to create a Book
  var book = new Book();
  book.name = 'AngularJS in nutshell';
  book.create();

  // to retrieve a book
  var bookPromise = Book.get(123);
  bookPromise.then(function(b) {
    book = b;
  });
};
Misko Hevery
fuente
1
Tal vez una pregunta novata, pero ¿cómo se podría extender esto para permitir un get () que devolviera múltiples respuestas, no solo una sola respuesta?
Nate Bunney
2
@NathanBunney, puede hacer que su método de obtención estático anterior recorra los resultados y cree una serie de libros.
Ben Lesh
44
@NathanBunney 'Book.getAll = function () {return $ http.get (' / Book '). Then (function (response) {var books = []; for (var i = 0; i <response.data.length ; i ++) {books.push (new Book (response.data [i]));} return books;}); }; '
Yair Nevet
2
¿Cómo compartirías una bookcolección de books entre los controladores?
Lukas
1
Esto es genial (obviamente desde que Misko creó el marco), pero estoy luchando por descubrir cómo hacerlo reutilizable. Si quisiera implementar las funciones CRUD solo una vez y luego heredar su funcionalidad en fábricas / servicios secundarios que solo necesitaban un argumento urlBase (preferiblemente almacenado en el prototipo para que cada instancia no necesitara una nueva copia de la urlBase), ¿cómo ¿Yo hago eso?
Dean Stamler
26

Te recomiendo que uses $ resource .

Puede admitir (anulación de URL) en la próxima versión de Angularjs. Entonces podrás codificar así:

// need to register as a serviceName
$resource('/user/:userId', {userId:'@id'}, {
    'customActionName':    {
        url:'/user/someURI'
        method:'GET',
        params: {
            param1: '....',
            param2: '....',
        }
    },
     ....
});

Y las devoluciones de llamada se pueden manejar en un alcance de Ctrl como este.

// ctrl scope
serviceName.customActionName ({
    paramName:'param',
    ...
}, 
function (resp) {
    //handle return callback
}, 
function (error) {
    //handler error callback
});

Probablemente pueda manejar código en un nivel de abstracción más alto.

nota de agradecimiento
fuente
2
La versión actual de angular.js admite la anulación de url en el módulo $ resource.
nota de agradecimiento
16
Jaja, está recomendando al creador real del marco sobre cómo hacer algo: P
HeberLZ
11
¡DIOS MIO! Me siento tan avergonzado.
nota de agradecimiento el