AngularJS1 + Django REST Frameworkに再挑戦 その10 ngResource Create & Delete
概要
AngularJS1 + Django REST Frameworkに再挑戦 その10 ngResource Create & Delete
参考動画
Django + AngularJS | Coding For Entrepreneurs
ngResource Create & Delete
ngResource を使って、commentをsave, deleteする機能を実装する。
blog-detail.component.jsを編集する。Commentのsave機能をつける。
... Comment.save({ //saveに必要な項目を代入する。 content: $scope.reply.content, slug: slug, type: "post" }, //ここからは、dataと、e_dataがある場合は、error_dataを表示するようなfunctionをセットしてある。 function(data){ // success console.log(data) }, function(e_data){ // error console.log(e_data) })
- これで、commentをsaveする機能がついた。あとは、今までのcomment createのコードをコメントアウトする。
... $scope.addReply = function() { console.log($scope.reply) var token = $cookies.get("token") if (token){ Comment.save({ content: $scope.reply.content, slug: slug, type: "post" }, function(data){ // success console.log(data) }, function(e_data){ // error console.log(e_data) }) // var req = { // method: "POST", // url: 'http://127.0.0.1:8000/api/comments/create/', // data:{ // content: $scope.reply.content, // slug: slug, // type: "post", // }, // headers:{ // authorization: "JWT " + token // } // } // // var requestAction = $http(req) // // requestAction.success(function(r_data, r_status, r_headers, r_config){ // $scope.comments.push($scope.reply) // resetReply() // }) // requestAction.error(function(e_data,e_status, e_headers, e_config){ // console.log(e_data) // }) // // $scope.comments.push($scope.reply) // // $scope.post.comments.push("abc") } else { ...
Failed to load resource: the server responded with a status of 405 (Method Not Allowed)
このままだとこのerrorが出てしまうので、ちょっと修正が必要。GETではなく、POSTでデータを送付する必要あり。全体を修正する。comment.service.jsに、commentCreateメソッドを追加する。
'use strict'; angular. module('core.comment'). factory('Comment', function($resource){ // こちらのurlは、commentのurlにセットする。 var url = '/api/comments/:id/' var commentQuery = { url: url, method: "GET", params: {}, isArray: true, cache: false, transformResponse: function(data, headerGetter, status){ // console.log(data) var finalData = angular.fromJson(data) return finalData.results } } var commentGet = { method: "GET", params: {"id": "@id"}, isArray: false, cache: false, } var commentCreate = { //こちらのurlは、djangoで設定したcommentsをcreateするurlを指定する。 url: '/api/comments/create/', method: "POST", // params: {"id": "@id"}, // isArray: false, // cache: false, } return $resource(url, {}, { query: commentQuery, get: commentGet, create: commentCreate, }) });
- headerの
statusText:"Unauthorized"というerrorが出て保存ができない!
comment.service.js`で、コメントアウトしたところに、headerにauthorizationを入れるコードがあったと思うので、それを利用して、認証をする。
... factory('Comment', function($cookies, $resource){ ... // cookiesからtokenをgetする。 var token = $cookies.get("token") if(token){ // headersにJWT tokenを代入する。 commentCreate["headers"] = {"Authorization": "JWT " + token} }
- これで一応は、登録ができるようになったけど、一度更新しないと、comment一覧に反映されないのがいまいち!なので、blog-detailページの処理を担当している、
blog-detail.compose.js
を修正する。
if (token){ Comment.create({ content: $scope.reply.content, slug: slug, type: "post" }, function(data){ // success //console.log(data) //ここを追加する $scope.comments.push(data) }, function(e_data){ // error console.log(e_data) })
これでリアルタイムに反映されるようになった!
次はdelete機能をつけていく。試しに
blog-detail.component.js
に、シンプルなdelete機能を追記してみる。
$scope.deleteComment = function(comment) { comment.$delete() // $scope.$apply( // $scope.comments.splice(comment, 1) // ) // someResource.$delete() }
- これで、deleteを試すと、
405 (Method Not Allowed)
が表示されてしまう。なので、createの時と同じように、comment.compose.js
に、commentDeleteメソッドを作成する。
... var commentDelete = { // urlは、commentsのidを選択する。 url: '/api/comments/:id/', // methodにDELETEを指定する。 method: "DELETE", // params: {"id": "@id"}, // isArray: false, // cache: false, } ... var token = $cookies.get("token") if(token){ commentCreate["headers"] = {"Authorization": "JWT " + token} //ここを追記する。 commentDelete["headers"] = {"Authorization": "JWT " + token} } return $resource(url, {}, { query: commentQuery, get: commentGet, create: commentCreate, delete: commentDelete })
- これで試してみると、
error
が表示されてしまう。どうも、comment_idが不明らしいということなので、deleteの際に、id
を追記する。blog-detail.component.jsを修正する。
... $scope.deleteComment = function(comment) { comment.$delete({"id": comment.id}) // $scope.$apply( // $scope.comments.splice(comment, 1) // ) // someResource.$delete() } ...
- これで一旦削除はできるようになった!次は、リアルタイムで画面から削除するコードを追記する。javascriptの、spliceメソッドを使う。多分これは、リストから指定した数の要素を削除するとかそういう意味だと思う。
$scope.deleteComment = function(comment) { comment.$delete({"id": comment.id}, function(data){ // success $scope.comments.splice(comment,1) }, function(e_data){ // error console.log(e_data) })
- 同じようにupdateReplyもaddReplyと似たような形で、実装できる。まずは、blog-detail.component.jsを修正する。
$scope.updateReply = function(comment) { Comment.update({ "id": comment.id, content: $scope.reply.content, slug: slug, type: "post" }, function(data){ //console.log(data) //$scope.comments.push(data) // resetReply() }, function(e_data){ // error console.log(e_data) }) }
- 次に、comment.service.jsを修正する。
... // まず、commentUpdateを作成する。 var commentUpdate = { url: '/api/comments/:id/', method: "PUT", // params: {"id": "@id"}, // isArray: false, // cache: false, } ... // 次に認証を作成する。 var token = $cookies.get("token") if(token){ commentCreate["headers"] = {"Authorization": "JWT " + token} commentDelete["headers"] = {"Authorization": "JWT " + token} commentUpdate["headers"] = {"Authorization": "JWT " + token} } ... // 最後にプロパティとして、登録する。 return $resource(url, {}, { query: commentQuery, get: commentGet, create: commentCreate, delete: commentDelete, update: commentUpdate, }) ...
- 結構ややこしいな。重要なのは、viewを修正することと、モデル(データ)を修正することは別々の機能として考えた方がわかりやすいということだね。