AngularJS $ resource RESTfulの例


145

$ resourceを使用してRESTful Webサービス(まだ作業中です)を呼び出したいのですが、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つのフィールドだけを更新できますか?このコードを正しく構築していますか?


2
$ resourceを基本的な$ httpサービスとして使用しているようです。$ resourceは、RESTfulデータソースからオブジェクトを取得し、それを操作して、で送り返すためのものobj.save()です。基本的な$ http実装を使用して、実行しようとしていることを実行できます。
Ben Lesh

4
@blesh彼がRESTful Webサービスと通信したいとき、なぜ$ resourceを使用すべきではないのですか?あなたが言ったように、それはまさにそれの目的ではないのですか?
F Lekschas

それは私を探しますが、$ resourceをサービスとして定義して注入します。これにより、必要に応じて、後で別の場所に簡単に再利用できます。
F Lekschas

4
@Flekええと、彼望むなら$ httpのような$ resource 使うことができます。しかし、それが実際に使用されることを意図した方法ではありません。
Ben Lesh

3
まあ、それは言うまでもなく、実際には「問題」ではありません。それは彼がRESTful APIと$ resourceが箱から出してあなたのためにできるすべてのものを利用していないことです。
Ben Lesh 2013

回答:


211

$ resourceは、エンドポイントからデータを取得し、それを操作して送り返すためのものでした。あなたはそこにそれのいくつかを持っていますが、あなたがそれをするために作られたもののためにそれを実際に活用していません。

リソースにカスタムメソッドを設定しても問題ありませんが、OOTBに付属する優れた機能を見逃したくない場合があります。

編集:私はこれを元々十分に説明したとは思いませんが、$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と約束

Angular 1.2以降、リソースは約束をサポートします。しかし、彼らは残りの行動を変えなかった。

でのpromiseを活用$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;
});

1
私はそうのような私の声明を絞り込むますね:あなたが使用していない場合は任意の $リソースのOOTB機能を、あなたはちょうどあなたが必要としないオブジェクトと関数参照でメモリを取っています。何かを傷つけるのでしょうか?おそらく違います。ただし、標準のCRUD操作を実行し、$ resourcesのニート機能を利用しない場合は、$ httpを使用する方が効率的です。
Ben Lesh

5
Blesh、OOTBの機能を超えるドキュメントはありますか?角度のドキュメントは混乱しています。
erichrusch 2013年

9
残念ながら、実際にはありません。私はGitHubでソースを掘り下げているところです。
Ben Lesh 2013年

2
Todo.get({id: 123});まっすぐなオブジェクトではなく、約束を返さないのですか?
インゴヴァルス2014

1
多分あなたは私の質問で私を助けることができます:stackoverflow.com/questions/30405569/…
AJ_83 2015年

0

あなたはただすることができます$scope.todo = Todo.get({ id: 123 }).get()そして、.query()リソースですぐにオブジェクトを返し、(自分のテンプレートを更新するために)後で約束の結果とそれを埋めます。それはだではない、あなたが呼び出した後に実行したいいくつかの特別なコードがある場合のいずれかのコールバックまたは$約束プロパティを使用する必要がある理由である典型的な約束。ただし、テンプレートでのみ使用している場合は、コールバックでスコープに割り当てる必要はありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.