Djangoroidの奮闘記

python,django,angularJS1~三十路過ぎたプログラマーの奮闘記

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を修正することと、モデル(データ)を修正することは別々の機能として考えた方がわかりやすいということだね。