더북(TheBook)

21.6.7 따라하기 6: ASP.NET Web API와 앵귤러를 사용한 SPA 구현

1. 앞의 제이쿼리 예제와 같은 내용을 이번에는 앵귤러를 사용해서 구현해보자. Maxim 폴더에 MaximCrudWithAngular라는 이름으로 HTML 문서를 생성하고 다음과 같이 코드를 작성한다.

▼  /Maxim/MaximCrudWithAngular.html

<!DOCTYPE html>
<html>
<head>
  <title>Angular + Web API를 사용한 CRUD 작업</title>
  <link href=”/Content/bootstrap.min.css” rel=“stylesheet” />
  <style>
      #divFullScreen {
          position: absolute;
          top: 0;
          left: 0;
          width: 100%;
          height: 100%;
          z-index: 1000;
          background-color: grey;
          opacity: .7;
      }
      
      .ajaxIndicator {
          position: absolute;
          left: 50%;
          top: 50%;
          margin-left: -32px;
          margin-top: -32px;
          display: block;
      }
  </style>
</head>
<body>
  <div ng-app=“maximApp”>
      <div data-ng-controller=“maximController” class=“container”>
          <h2>{{ title }}</h2>
          <div class=“row”>
              <div class=“col-md-12”>
                  <strong class=“error”>{{ error }}</strong>
                  <p data-ng-hide=“isAddMode”>
                      <a data-ng-click=“changeAddMode()”
                         class=“btn btn-primary”>내용 추가하기</a>
                  </p>
                  <form name=“frmAddMaxim” id=“frmAddMaxim”
                        data-ng-show=“isAddMode”
                        style=“width:600px;margin:0 auto;”>
                      <div class=“form-group”>
                          <label for=“cname”
                                 class=“col-sm-2 control-label”>이름:</label>
                          <div class=“col-sm-10”>
                              <input type=“text” class=“form-control”
                                     id=“name” placeholder=“이름”
                                     required
                                     ng-minlength=“1”
                                     ng-maxlength=“25”
                                     data-ng-model=“maximInput.name” />
                          </div>
                      </div>
                      <div class=“form-group”>
                          <label for=“content”
                                 class=“col-sm-2 control-label”>내용:</label>
                          <div class=“col-sm-10”>
                              <input type=“text” class=“form-control”
                                     id=“content” placeholder=“명언”
                                     required
                                     ng-minlength=“3”
                                     ng-maxlength=“255”
                                     data-ng-model=“maximInput.content” />
                          </div>
                      </div>
                      <br />
                      <div class=“form-group”>
                          <div class=“col-sm-offset-2 col-sm-10”>
                              <input type=“submit” value=“입력”
                                     data-ng-click=“add()”
                                     data-ng-disabled=”!frmAddMaxim.$valid”
                                     class=“btn btn-primary” />
                              <input type=“button” value=“취소”
                                     data-ng-click=“changeAddMode()”
                                     class=“btn btn-primary” />
                          </div>
                      </div>
                      <br />
                  </form>
              </div>
          </div>
          <div class=“row”>
              <div class=“col-md-12”>
                  <div class=“table-responsive”>
                      <table class=“table table-bordered table-hover”
                             style=“width:100%;”>
                          <tr>
                              <th>#</th>
                              <td>이름</td>
                              <th>명언</th>
                              <th></th>
                          </tr>
                          <tr data-ng-repeat=“maxim in maxims”>
                              <td>
                                  <strong data-ng-hide=“maxim.editStatus”>
                                      {{ maxim.id }}
                                  </strong>
                              </td>
                              <td>
                                  <p data-ng-hide=“maxim.editStatus”>
                                      {{ maxim.name }}
                                  </p>
                                  <input type=“text”
                                         data-ng-show=“maxim.editStatus”
                                         data-ng-model=“maxim.name” />
                              </td>
                              <td>
                                  <p data-ng-hide=“maxim.editStatus”>
                                      {{ maxim.content }}
                                  </p>
                                  <input type=“text”
                                         data-ng-show=“maxim.editStatus”
                                         data-ng-model=“maxim.content” />
                              </td>
                              <td>
                                  <p data-ng-hide=“maxim.editStatus”>
                                      <a ng-click=“changeEditStatus(maxim)”
                                         href=“javascript:;”>수정</a> |
                                      <a data-ng-click=“remove(maxim)”
                                         href=“javascript:;”>삭제</a>
                                  </p>
                                  <p ng-show=“maxim.editStatus”>
                                      <a ng-click=“save(maxim)”
                                         href=“javascript:;”>저장</a> |
                                      <a ng-click=“changeEditStatus(maxim)”
                                         href=“javascript:;”>취소</a>
                                  </p>
                              </td>
                          </tr>
                      </table>
                  </div>
              </div>
          </div>
          <div id=“divFullScreen” data-ng-show=“loading”>
              <img src=”/images/ajaxIndicator.gif” class=“ajaxIndicator” />
          </div>
      </div>
  </div>
  
  
  
  <script src=”/Scripts/jquery-2.1.3.min.js”></script>
  <script src=”/Scripts/bootstrap.min.js”></script>
  <script src=”/Scripts/angular.min.js”></script>
  <script>
      (function () {
          ‘use strict’;
          
          // [1] Angualr 모듈 선언
          var app = angular.module(‘maximApp’, []);
          
          // [2][1] Angualr 컨트롤러 선언
          app.controller(‘maximController’
              , [’$scope’, ’$http’, maximController]);
          
          // [2][2] 컨트롤러 구현부
          function maximController($scope, $http) {
              
              // Web API 주소: ASP.NET Web API로 구현
              // const API_URL = “/api/maximservice/”;
              var API_URL = ”/api/maximservice/”;
              
              // 속성(Property)
              $scope.title = “명언 관리”;
              $scope.loading = true; // 로딩 창 띄우기
              $scope.isAddMode = false; // 입력 모드(true: 입력 폼 출력)
              
              // 입력 값 임시 저장용 개체
              $scope.maximInput = {
                  id: 0,
                  name: ,
                  content: ,
              };
              
              // 메서드(함수, Function)
              $scope.changeEditStatus = function () {
                  this.maxim.editStatus = !this.maxim.editStatus;
              };
              
              $scope.changeAddMode = function () {
                  $scope.isAddMode = !$scope.isAddMode;
              };
              
              
              // 출력: GET
              $http.get(API_URL).success(function (data) {
                  $scope.maxims = data;
                  $scope.loading = false;
              })
              .error(function () {
                  $scope.error = “데이터를 가져오는 동안 에러가 발생했습니다. “;
                  $scope.loading = false;
              });
              
              
              // 입력: POST
              $scope.add = function () {
                  $scope.loading = true;
                  
                  // POST: get()의 success().error() 대신 then(f,f) 사용 가능
                  $http.post(API_URL, $scope.maximInput)
                      .then(function (result) {
                          alert(“데이터가 입력되었습니다.”);
                          $scope.isAddMode = false;
                          $scope.maxims.push(result.data); // resut.data 주의
                          $scope.loading = false;
                          
                          $scope.maximInput = {}; // 입력 폼 클리어
                      }, function (error) {
                          $scope.error =
                              “데이터를 입력하는 동안 에러가 발생했습니다. “
                              + error.data.ExceptionMessage; // 또 다른 방법
                          $scope.loading = false;
                      });
              };
              
              
              // 수정: PUT
              $scope.save = function () {
                  $scope.loading = true;
                  var maxim = this.maxim;
                  
                  // PUT
                  $http.put(API_URL + maxim.id, maxim).success(
                      function (data) {
                          alert(“데이터가 수정되었습니다.”);
                          maxim.editStatus = false;
                          $scope.loading = false;
                      })
                  .error(function (data) {
                      $scope.error =
                          “데이터를 수정하는 동안 에러가 발생했습니다. “ + data;
                      $scope.loading = false;
                  });
              };
              
              
              // 삭제: DELETE
              $scope.remove = function () {
                  $scope.loading = true;
                  var id = this.maxim.id;
                  
                  // DELETE
                  $http.delete(API_URL + id).success(function (data) {
                      alert(“데이터가 삭제되었습니다.”);
                      $.each($scope.maxims, function (i) {
                          if ($scope.maxims[i].id === id) {
                              $scope.maxims.splice(i, 1);
                              return false;
                          }
                      });
                      $scope.loading = false;
                  })
                  .error(function (data) {
                      $scope.error =
                          “데이터를 삭제하는 동안 에러가 발생했습니다. “ + data;
                      $scope.loading = false;
                  });
              };
          } // maximController
      })();
  </script>
</body>
</html>

신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.