私はRESTfulなWebサービスを呼び出すために$ resourceを使いたいのですが(私はまだ取り組んでいます)、AngularJSスクリプトが最初に正しいかどうかを調べたいと思います。
ToDo DTOには次のものがあります。{id, order, content, done}
:cmd
は、api/1/todo/reset
を呼び出して、データベース内のToDoテーブルをクリアすることができます。
これが私の理解のコメント付きのコードです:
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();
}
私が確信が持てない1つの特別なことはPATCHメソッドです、私はすべてを更新したくありません、私は1つのフィールドだけを更新することができますか?このコードを正しく構築できますか?
$ resourceは、エンドポイントからデータを取得し、それを操作して送り返すためのものです。そこにはいくつかのがありますが、実際に行われていることにそれを利用しているわけではありません。
リソースにカスタムメソッドを設定しても問題ありませんが、OOTBに搭載されている優れた機能を見逃したくはありません。
EDIT:私はもともとこれについて十分に説明したとは思いませんが、$resource
はリターンに関していくつかのファンキーなことをします。 Todo.get()
およびTodo.query()
は両方ともリソースオブジェクトを返し、およびそれをコールバックに渡しますgetが完了したとき$save()
コールバックが実際に起動する前にget()
を呼び出すことができるという意味で、舞台裏での約束を巧妙に組み合わせて実行しています。リソースをpromise then()
またはコールバックメソッドの中で扱うことがおそらく最善です。
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});
同様に、OPに投稿したものの場合は、リソースオブジェクトを取得してから、その上に任意のカスタム関数を呼び出すことができます(理論上)。
var something = src.GetTodo({id: 123});
something.foo = 'hi there';
something.UpdateTodo();
私が行って自分のものを発明する前に、私はOOTB実装を試してみました。 $resource
のデフォルトの機能を使っていないのなら、おそらく$http
を自分で使うべきでしょう。
Angular 1.2以降、リソースは約束をサポートします。しかし、彼らは他の振る舞いを変えませんでした。
$resource
でpromiseを活用するには、戻り値に$promise
プロパティを使用する必要があります。
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
});
$promise
プロパティは、上で返されていたのと同じ値を持つプロパティであることを忘れないでください。だからあなたは奇妙になることができます:
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;
});
あなただけの$scope.todo = Todo.get({ id: 123 })
を行うことができます。リソース上の.get()
と.query()
はすぐにオブジェクトを返し、(テンプレートを更新するために)後で約束の結果で埋めます。これはではない典型的な約束であり、呼び出しの後に実行したい特別なコードがある場合はコールバックまたは$ promiseプロパティを使用する必要があります。ただし、テンプレートでのみ使用している場合は、コールバックでそれをスコープに割り当てる必要はありません。