AngularJS $ resource RESTful Beispiel

145

Ich möchte $ resource verwenden, um meinen RESTful-Webdienst aufzurufen (an dem ich noch arbeite), aber ich möchte zuerst herausfinden, ob mein AngularJS-Skript korrekt ist.

Das todo DTO hat: {id, order, content, done}

:cmdist so kann ich aufrufen api/1/todo/reset, um die ToDo-Tabelle in der Datenbank zu löschen.

Hier ist der Code mit einem Kommentar meines Verständnisses:

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

Ich bin mir nicht sicher, ob es sich um die PATCH-Methode handelt. Ich möchte nicht alles aktualisieren. Kann ich nur ein Feld aktualisieren? Konstruiere ich diesen Code richtig?

Tom
quelle
2
Es sieht so aus, als würden Sie $ resource als grundlegenden $ http-Dienst verwenden. $ resource dient eher dazu, ein Objekt aus einer RESTful-Datenquelle abzurufen, zu bearbeiten und dann mit zurückzusenden obj.save(). Sie können das tun, was Sie mit einer grundlegenden $ http-Implementierung versuchen.
Ben Lesh
4
@blesh warum sollte er $ resource nicht verwenden, wenn er mit seinem RESTful-Webservice kommunizieren möchte? Wie Sie sagten, ist das nicht genau der Zweck davon?
F Lekschas
Es sieht für mich so aus, aber ich würde die $ resource als Service definieren und einfügen. Auf diese Weise können Sie es später bei Bedarf problemlos an einem anderen Ort wiederverwenden.
F Lekschas
4
@Flek Nun, er kann $ resource wie $ http verwenden, wenn er möchte . Aber so sollte es eigentlich nicht verwendet werden.
Ben Lesh
3
Nun, es ist nicht wirklich ein "Problem". Es ist mehr so, dass er die RESTful-API und all die Dinge, die $ resource sofort für Sie tun kann, nicht ausnutzt.
Ben Lesh

Antworten:

211

$ resource sollte Daten von einem Endpunkt abrufen, bearbeiten und zurücksenden. Sie haben etwas davon drin, aber Sie nutzen es nicht wirklich für das, wofür es gemacht wurde.

Es ist in Ordnung, benutzerdefinierte Methoden für Ihre Ressource zu haben, aber Sie möchten nicht auf die coolen Funktionen verzichten, die mit OOTB geliefert werden.

EDIT : Ich glaube nicht, dass ich das ursprünglich gut genug erklärt habe, aber ich $resourcemache ein paar funky Sachen mit Retouren. Todo.get()und Todo.query()beide geben das Ressourcenobjekt zurück und übergeben es an den Rückruf, wenn der Abruf abgeschlossen ist. Es macht einige ausgefallene Sachen mit Versprechungen hinter den Kulissen, die bedeuten, dass Sie anrufen können, $save()bevor der get()Rückruf tatsächlich ausgelöst wird, und es wird warten. Es ist wahrscheinlich am besten, nur mit Ihrer Ressource innerhalb eines Versprechens then()oder der Rückrufmethode umzugehen .

Standardgebrauch

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

Ebenso könnten Sie im Fall von dem, was Sie im OP gepostet haben, ein Ressourcenobjekt abrufen und dann (theoretisch) eine Ihrer benutzerdefinierten Funktionen darauf aufrufen:

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

Ich würde mit der OOTB-Implementierung experimentieren, bevor ich meine eigene erfand. Und wenn Sie feststellen, dass Sie keine der Standardfunktionen von verwenden $resource, sollten Sie diese wahrscheinlich nur $httpalleine verwenden.

Update: Angular 1.2 und Versprechen

Ab Angular 1.2 unterstützen Ressourcen Versprechen. Aber sie haben den Rest des Verhaltens nicht geändert.

Um Versprechen zu nutzen $resource, müssen Sie die $promiseEigenschaft für den zurückgegebenen Wert verwenden.

Beispiel mit Versprechungen

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

Denken Sie daran, dass die $promiseEigenschaft eine Eigenschaft mit denselben Werten ist, die sie oben zurückgegeben hat. So können Sie komisch werden:

Diese sind gleichwertig

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;
});
Ben Lesh
quelle
1
Ich denke, ich werde meine Aussage folgendermaßen verfeinern: Wenn Sie keine OOTB-Funktionen von $ resource verwenden, belegen Sie nur Speicher mit Objekt- und Funktionsreferenzen, die Sie nicht benötigen. Wird es irgendetwas verletzen? Wahrscheinlich nicht. Es kann jedoch effizienter sein, nur $ http zu verwenden, wenn Sie nur Standard-CRUD-Operationen ausführen und keine $ resources-Neato-Funktionen nutzen.
Ben Lesh
5
Meine Güte, gibt es Dokumente, die über die OOTB-Funktionalität gehen? Die eckigen Dokumente sind verwirrend.
Erichrusch
9
Leider gibt es das nicht wirklich. Ich habe gerade ihre Quelle auf GitHub durchgesehen.
Ben Lesh
2
Gibt kein Todo.get({id: 123});Versprechen und kein direktes Objekt zurück?
Ingó Vals
1
Vielleicht können Sie mir bei meiner Frage helfen: stackoverflow.com/questions/30405569/… .
AJ_83
0

du kannst es einfach tun $scope.todo = Todo.get({ id: 123 }). .get()und .query()auf einer Ressource ein Objekt sofort zurückgeben und es später mit dem Ergebnis des Versprechens füllen (um Ihre Vorlage zu aktualisieren). Es ist kein typisches Versprechen, weshalb Sie entweder einen Rückruf oder die Eigenschaft $ versprechen verwenden müssen, wenn Sie einen speziellen Code haben, den Sie nach dem Aufruf ausführen möchten. Es ist jedoch nicht erforderlich, es in einem Rückruf Ihrem Bereich zuzuweisen, wenn Sie es nur in der Vorlage verwenden.

William B.
quelle