Esempio RESTful di risorse AngularJS $


145

Vorrei usare $ resource per chiamare il mio servizio web RESTful, (su cui sto ancora lavorando), ma vorrei scoprire se il mio script AngularJS è stato corretto per primo.

Il todo DTO ha: {id, order, content, done}

:cmdè così che posso chiamare api/1/todo/resetper cancellare la tabella todo nel database.

Ecco il codice con il commento della mia comprensione:

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 particolare di cui non sono sicuro è il metodo PATCH, non voglio aggiornare tutto, posso aggiornare solo un campo? Sto costruendo correttamente questo pezzo di codice?


2
Sembra che tu stia utilizzando $ resource come servizio $ http di base. $ resource è di più per ottenere un oggetto da un'origine dati RESTful, manipolarlo e poi rispedirlo con obj.save(). Potresti fare quello che stai cercando di fare con un'implementazione $ http di base.
Ben Lesh,

4
@blesh perché non dovrebbe usare $ resource quando vuole comunicare con il suo servizio web RESTful? Come hai detto, non è esattamente questo lo scopo?
F Lekschas,

Mi cerca ma definirei la risorsa $ come servizio e la inietterei. Ciò ti consente di riutilizzarlo facilmente da qualche altra parte in seguito, se necessario.
F Lekschas,

4
@Flek Beh, può usare $ risorse come $ http se lo desidera . Ma non è proprio così che doveva essere usato.
Ben Lesh,

3
Bene, non è davvero un "problema", per dire. È più che non sta sfruttando l'API RESTful e tutte le cose che $ resource può fare per te fuori dalla scatola.
Ben Lesh,

Risposte:


211

$ resource doveva recuperare i dati da un endpoint, manipolarli e rispedirli. Ne hai un po ' lì dentro, ma non lo stai davvero sfruttando per quello che è stato fatto per fare.

Va bene avere metodi personalizzati sulla tua risorsa, ma non vuoi perderti le fantastiche funzionalità di OOTB.

EDIT : Non penso che ho spiegato questo abbastanza bene in origine, ma $resourcefa alcune cose funky con rendimenti. Todo.get()ed Todo.query()entrambi restituiscono l'oggetto risorsa e lo passano nel callback per quando il get è completo. Fa alcune cose fantasiose con promesse dietro le quinte che significano che puoi chiamare $save()prima che il get()callback si attivi, e aspetterà. Probabilmente è meglio solo gestire la tua risorsa all'interno di una promessa then()o del metodo di callback.

Uso standard

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});

Allo stesso modo, nel caso di ciò che è stato pubblicato nell'OP, è possibile ottenere un oggetto risorsa e quindi chiamare una delle funzioni personalizzate su di esso (teoricamente):

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

Sperimenterei l'implementazione di OOTB prima di andare a inventare la mia. E se scopri che non stai utilizzando nessuna delle funzionalità predefinite di $resource, probabilmente dovresti semplicemente usarlo $httpda solo.

Aggiornamento: Angolare 1.2 e promesse

A partire da Angular 1.2, le risorse supportano le promesse. Ma non hanno cambiato il resto del comportamento.

Per sfruttare le promesse $resource, è necessario utilizzare la $promiseproprietà sul valore restituito.

Esempio usando le promesse

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
});

Basta tenere presente che la $promiseproprietà è una proprietà sugli stessi valori che stava tornando sopra. Quindi puoi diventare strano:

Questi sono equivalenti

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
Immagino che affinerò la mia affermazione in questo modo: se non stai usando alcuna funzionalità OOTB di $ resource, allora stai solo occupando memoria con riferimenti a oggetti e funzioni che non ti servono. Farà del male a qualcosa? Probabilmente no. Ma potrebbe essere più efficiente utilizzare $ http solo se si eseguono operazioni CRUD standard e non si sfruttano le risorse $ neato.
Ben Lesh,

5
Blesh, ci sono dei documenti che vanno oltre la funzionalità OOTB? I documenti angolari sono confusi.
Erichrusch,

9
Purtroppo, non c'è, davvero. Ho appena cercato la loro fonte su GitHub.
Ben Lesh,

2
Non Todo.get({id: 123});restituisce una promessa e non un oggetto semplice?
Ingó Vals,

1
Forse puoi aiutarmi con la mia domanda: stackoverflow.com/questions/30405569/… .
AJ_83,

0

puoi semplicemente fare $scope.todo = Todo.get({ id: 123 }). .get()e .query()su una risorsa restituisci immediatamente un oggetto e riempilo con il risultato della promessa in seguito (per aggiornare il tuo modello). E ' non è una promessa tipica che è il motivo per cui è necessario utilizzare su un callback o la proprietà $ promessa se si dispone di un codice speciale che si desidera eseguire dopo la chiamata. Ma non è necessario assegnarlo al proprio ambito in un callback se lo si utilizza solo nel modello.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.