AngularJS $ resource RESTful ejemplo


145

Me gustaría usar $ resource para llamar a mi servicio web RESTful, (en el que todavía estoy trabajando), pero me gustaría saber si primero obtuve mi script AngularJS correcto.

El todo DTO tiene: {id, order, content, done}

:cmdes así que puedo llamar api/1/todo/resetpara borrar la tabla de tareas en la base de datos.

Aquí está el código con comentario de mi comprensión:

function TodoService($resource) {
    var src = $resource('api/1/todo/:id:cmd',
              {id: "@id", cmd: "@cmd"}, //parameters default
              {
                ListTodos: { method: "GET", params: {} },
                GetTodo: { method: "GET", params: { id: 0 } },                            
                CreateTodo: { method: "POST", params: { content: "", order: 0, done: false } },
                UpdateTodo: { method: "PATCH", params: { /*...*/ } },
                DeleteTodo: { method: "DELETE", params: { id: 0 } },
                ResetTodos: { method: "GET", params: { cmd: "reset" } },
              });

    //Usage:

    //GET without ID
    //it calls -> api/1/todo
    src.ListTodos();

    //GET with ID
    //it calls -> api/1/todo/4
    src.GetTodo({ id: 4 });

    //POST with content, order, done
    //it calls -> api/1/todo
    src.CreateTodo({ content: "learn Javascript", order: 1, done: false });

    //UPDATE content only
    //it calls -> api/1/todo/5
    src.UpdateTodo({ id: 5, content: "learn AngularJS" }); 

    //UPDATE done only
    //it calls -> api/1/todo/5
    src.UpdateTodo({ id: 5, done: true });

    //RESET with cmd
    //it calls -> api/1/todo/reset
    src.ResetTodos();
}

Una cosa en particular que no estoy seguro es el método PATCH, no quiero actualizar todo, ¿puedo actualizar solo un campo? ¿Estoy construyendo este código correctamente?


2
Parece que estás usando $ resource como un servicio básico $ http. $ resource es más para obtener un objeto de una fuente de datos RESTful, manipularlo y luego enviarlo de vuelta con obj.save(). Podrías hacer lo que estás intentando hacer con una implementación básica de $ http.
Ben Lesh

44
@blesh ¿por qué no debería usar $ resource cuando quiere comunicarse con su servicio web RESTful? Como dijiste, ¿no es ese exactamente el propósito?
F Lekschas

Me busca pero definiría el $ resource como un servicio y lo inyectaría. Esto le permite reutilizarlo fácilmente en otro lugar más tarde, si es necesario.
F Lekschas

44
@Flek Bueno, puede usar $ resource como $ http si lo desea . Pero esa no es realmente la forma en que debía usarse.
Ben Lesh, el

3
Bueno, no es realmente un "problema", por decir. Es más que no está aprovechando la API RESTful y todas las cosas que $ resource puede hacer por usted de inmediato.
Ben Lesh

Respuestas:


211

$ resource estaba destinado a recuperar datos de un punto final, manipularlos y devolverlos. Tienes algunos de eso allí, pero realmente no lo estás aprovechando para lo que fue hecho para hacer.

Está bien tener métodos personalizados en su recurso, pero no quiere perderse las características geniales que viene con OOTB.

EDITAR : No creo que haya explicado esto bastante bien originalmente, pero $resourcehace algunas cosas funky con devoluciones. Todo.get()y Todo.query()ambos devuelven el objeto de recurso y lo pasan a la devolución de llamada para cuando se complete el get. Hace algunas cosas elegantes con promesas detrás de escena que significan que puede llamar $save()antes de que la get()devolución de llamada realmente se active, y esperará. Probablemente sea mejor tratar su recurso dentro de una promesa then()o el método de devolución de llamada.

Uso estándar

var Todo = $resource('/api/1/todo/:id');

//create a todo
var todo1 = new Todo();
todo1.foo = 'bar';
todo1.something = 123;
todo1.$save();

//get and update a todo
var todo2 = Todo.get({id: 123});
todo2.foo += '!';
todo2.$save();

//which is basically the same as...
Todo.get({id: 123}, function(todo) {
   todo.foo += '!';
   todo.$save();
});

//get a list of todos
Todo.query(function(todos) {
  //do something with todos
  angular.forEach(todos, function(todo) {
     todo.foo += ' something';
     todo.$save();
  });
});

//delete a todo
Todo.$delete({id: 123});

Del mismo modo, en el caso de lo que publicó en el OP, podría obtener un objeto de recurso y luego llamar a cualquiera de sus funciones personalizadas (teóricamente):

var something = src.GetTodo({id: 123});
something.foo = 'hi there';
something.UpdateTodo();

Sin embargo, experimentaría con la implementación OOTB antes de ir e inventar la mía. Y si descubres que no estás usando ninguna de las funciones predeterminadas de $resource, probablemente deberías estar usando $httpsolo.

Actualización: Angular 1.2 y promesas

A partir de Angular 1.2, los recursos respaldan las promesas. Pero no cambiaron el resto del comportamiento.

Para aprovechar las promesas $resource, debe usar la $promisepropiedad en el valor devuelto.

Ejemplo usando promesas

var Todo = $resource('/api/1/todo/:id');

Todo.get({id: 123}).$promise.then(function(todo) {
   // success
   $scope.todos = todos;
}, function(errResponse) {
   // fail
});

Todo.query().$promise.then(function(todos) {
   // success
   $scope.todos = todos;
}, function(errResponse) {
   // fail
});

Solo tenga en cuenta que la $promisepropiedad es una propiedad con los mismos valores que estaba devolviendo anteriormente. Entonces puedes ponerte raro:

Estos son equivalentes

var todo = Todo.get({id: 123}, function() {
   $scope.todo = todo;
});

Todo.get({id: 123}, function(todo) {
   $scope.todo = todo;
});

Todo.get({id: 123}).$promise.then(function(todo) {
   $scope.todo = todo;
});

var todo = Todo.get({id: 123});
todo.$promise.then(function() {
   $scope.todo = todo;
});

1
Supongo que refinaré mi declaración de la siguiente manera: si no está utilizando ninguna característica OOTB de $ resource, solo está ocupando memoria con referencias de objetos y funciones que no necesita. ¿Va a doler algo? Probablemente no. Pero puede ser más eficiente usar $ http si solo está realizando operaciones CRUD estándar y no aprovecha las funciones neato de $ resources.
Ben Lesh

55
Blesh, ¿hay algún documento que revise la funcionalidad OOTB? Los documentos angulares son confusos.
erichrusch

9
Lamentablemente, no hay, realmente. He estado cavando a través de su fuente en GitHub.
Ben Lesh

2
¿No Todo.get({id: 123});devuelve una promesa y no un objeto directo?
Ingó Vals

1
Quizás pueda ayudarme con mi pregunta: stackoverflow.com/questions/30405569/… .
AJ_83

0

solo puedes hacer $scope.todo = Todo.get({ id: 123 }). .get()y .query()en un Recurso, devuelva un objeto inmediatamente y llénelo con el resultado de la promesa posterior (para actualizar su plantilla). Es no una promesa típica por lo que es necesario utilizar ya sea una devolución de llamada o la propiedad $ promesa si tiene algún código especial que desea ejecutar después de la llamada. Pero no es necesario asignarlo a su alcance en una devolución de llamada si solo lo está utilizando en la plantilla.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.