<!--
이 파일을 테스트를 돕는데 사용합니다.
따라서, 예제와 관련없는 내용입니다.
-->
<!DOCTYPE html>
<html>

  <head>
    <link data-require="angular.js@1.7.8" data-semver="1.7.8" rel="stylesheet" href="https://code.angularjs.org/1.7.8/angular-csp.css" />
    <link data-require="bootstrap@3.3.7" data-semver="3.3.7" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
    <script data-require="jquery@*" data-semver="3.2.1" src="https://cdn.jsdelivr.net/npm/jquery@3.2.1/dist/jquery.min.js"></script>
    <script data-require="bootstrap@3.3.7" data-semver="3.3.7" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
    <script data-require="angular.js@1.7.8" data-semver="1.7.8" src="https://code.angularjs.org/1.7.8/angular.min.js"></script>
    <script data-require="angular.js@1.7.8" data-semver="1.7.8" src="https://code.angularjs.org/1.7.8/angular-animate.min.js"></script>
    <script data-require="angular.js@1.7.8" data-semver="1.7.8" src="https://code.angularjs.org/1.7.8/angular-sanitize.min.js"></script>
    <script data-require="underscore.js@*" data-semver="1.8.3" src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
    <script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-2.5.0.js"></script>
    <script src="samplehelp.js"></script>
    <script src="SimpleUserInfoManagement.js"></script>
    <script src="SimpleUserInfoManagement-Locale_KR.js"></script>
  </head>

  <body>
    <div class="container-fluid">
      <!-- @RenderBody()  -->
      <ng-include src="'SimpleUserInfoManagement.cshtml'"></ng-include>
      <!-- @RenderBody() End -->
    </div>
  </body>
</html>
$tq(function(module) {
  module.service('Page.SimpleUserInfoManagement.svc', ['$fakeHttp', function($http) {
    return {
      // 고객리스트 가져오기
      GetAllUsers: function() {
        return $http.post('/SimpleUserInfoManagement/GetAllUsers');
      },
      // 고객삭제
      DeleteUserById: function(id) {
        return $http.post('/SimpleUserInfoManagement/DeleteUserById', id);
      },
      // 고객등록
      AddNewUserAndGet: function(item) {
        return $http.post('/SimpleUserInfoManagement/AddNewUserAndGet', item);
      },
      UserInfoModification: function(item){
        return $http.post('/SimpleUserInfoManagement/UserInfoModification', item);
      }
    };
  }]);
  module.controller('Page.SimpleUserInfoManagementCtrl', ['$scope', 'Page.SimpleUserInfoManagement.Locale', 'Page.SimpleUserInfoManagement.svc', '$uibModal',
    function($scope, Locale, svc, $uibModal) {
      var ctrl = this;
      // evt
      $scope.evt = {
          remove: function(item) {
            return svc.DeleteUserById(item.Id).then(initUserlist);
          },
          addNew: function() {
            return openNewUserModal().result.then(initUserlist);
          },
          update: function(item) {
            return openUpdateUserModal(item).result.then(initUserlist);
          }
        }
        // fn
        // 고객리스트 초기화
      function initUserlist() {
        return svc.GetAllUsers().then(function(res) {
          ctrl.userlist = res.data;
        });
      }

      function openNewUserModal() {
        return $uibModal.open({
          templateUrl: 'AddNewModal.tmpl.html',
          controller: 'Page.SimpleUserInfoManagement.AddNewModalCtrl',
          controllerAs: 'ctrl'
        });
      }

      function openUpdateUserModal(item) {
        return $uibModal.open({
          templateUrl: 'UpdateModal.tmpl.html',
          controller: 'Page.SimpleUserInfoManagement.UpdateModalCtrl',
          controllerAs: 'ctrl',
          resolve: {
            items: function(){
              return {item: _.clone(item)};
            }
          }
        });
      }

      // init
      ctrl.$onInit = function() {
        // init model
        $scope.L = Locale;
        ctrl.userlist = [];
        initUserlist();
      }
    }
  ]);
  module.controller('Page.SimpleUserInfoManagement.AddNewModalCtrl', ['$scope', 'Page.SimpleUserInfoManagement.Locale', 'Page.SimpleUserInfoManagement.svc', '$uibModalInstance',
    function($scope, Locale, svc, $uibModalInstance) {
      var ctrl = this;
      // evt
      $scope.evt = {
          submit: function() {
            if (checkInvalid()) return;
            return svc.AddNewUserAndGet(ctrl.item).then(closeModal);
          }
        }
        // fn
      function checkInvalid() {
        return $scope.frmAddNew.$invalid;
      }

      function closeModal() {
        $uibModalInstance.close();
      }

      // init
      ctrl.$onInit = function() {
        $scope.L = Locale;
        ctrl.item = {}
      }
    }
  ]);
  module.controller('Page.SimpleUserInfoManagement.UpdateModalCtrl', ['$scope', 'Page.SimpleUserInfoManagement.Locale', 'Page.SimpleUserInfoManagement.svc', '$uibModalInstance', 'items',
    function($scope, Locale, svc, $uibModalInstance, items) {
      var ctrl = this;
      // evt
      $scope.evt = {
          submit: function() {
            if (checkInvalid()) return;
            return svc.UserInfoModification(ctrl.item).then(closeModal);
          }
        }
        // fn
      function checkInvalid() {
        return $scope.frmAddNew.$invalid;
      }

      function closeModal() {
        $uibModalInstance.close();
      }

      // init
      ctrl.$onInit = function() {
        $scope.L = Locale;
        ctrl.item = items.item;
      }
    }
  ]);
})(angular.module('Page.SimpleUserInfoManagement', []));
/*
이 파일을 테스트를 돕는데 사용합니다.
따라서, 예제와 관련없는 내용입니다.
*/
console.clear();
(function() {
  var _maxId = 3;
  var _userlist = [{
    Id: 1,
    FullName: '정유성',
    Age: 29,
    BirthDay: '2019-01-01'
  }, {
    Id: 2,
    FullName: '김나영',
    Age: 37,
    BirthDay: '2010-12-11'
  }, {
    Id: 3,
    FullName: '이진영',
    Age: 32,
    BirthDay: '2008-04-25'
  }];


  // app start
  var app = window['app'] = angular.module('app', ['ngAnimate', 'ngSanitize', 'ui.bootstrap']);

  app.service('$fakeHttp', ['$q', function($q) {
    return {
      post: function(url) {
        var defer = $q.defer();

        switch (url) {
          case '/SimpleUserInfoManagement/GetAllUsers':
            defer.resolve({
              data: _userlist
            });
            break;
          case '/SimpleUserInfoManagement/AddNewUserAndGet':
            _maxId++;
            _userlist.push({
              Id: _maxId,
              FullName: arguments[1].FullName,
              Age: arguments[1].Age,
              BirthDay: arguments[1].BirthDay
            });
            defer.resolve({
              data: _maxId
            });
            break;
          case '/SimpleUserInfoManagement/DeleteUserById':
            var find = _.findWhere(_userlist, {
              Id: arguments[1]
            });
            if (find) {
              var idx = _userlist.indexOf(find);
              _userlist.splice(idx, 1);
            }
            defer.resolve();
            break;
          case '/SimpleUserInfoManagement/UserInfoModification':
            var find = _.findWhere(_userlist, {
              Id: arguments[1].Id
            });
            if (find) {
              var idx = _userlist.indexOf(find);
              _userlist[idx] = arguments[1];
            }
            defer.resolve();
          default:
            defer.reject();
            break;
        }
        return defer.promise;
      }
    };
  }]);

  function $tq(fn) {
    return function(module) {
      if (app.requires.indexOf(module.name) == -1) {
        app.requires.push(module.name);
      }
      fn.apply(this, arguments);
    }
  }

  window['$tq'] = $tq;

  angular.element(function bootstrap() {
    angular.bootstrap(document, ['app']);
  });
})();
<!-- SimpleUserInfoManagement.cshtml -->
<div class="col col-md-12" ng-controller="Page.SimpleUserInfoManagementCtrl as ctrl">
  <h2 class="page-header">{{::L.Title}}</h2>
  <table class="table table-borded">
    <thead>
      <tr>
        <th>{{::L.TableHeaders.Id}}</th>
        <th>{{::L.TableHeaders.FullName}}</th>
        <th>{{::L.TableHeaders.Age}}</th>
        <th>{{::L.TableHeaders.BirthDay}}</th>
        <th>
          <button class="btn btn-primary btn-sm" ng-click="evt.addNew()">{{::L.Buttons.Reg}}</button>
          <th>
      </tr>
    </thead>
    <tbody>
      <tr ng-repeat="item in ctrl.userlist">
        <td>{{item.Id}}</td>
        <td>{{item.FullName}}</td>
        <td>{{item.Age}}</td>
        <td>{{item.BirthDay}}</td>
        <td style="width:120px">
          <button class="btn btn-danger btn-sm" ng-click="evt.remove(item)">{{::L.Buttons.Del}}</button>
          <button class="btn btn-warning btn-sm" ng-click="evt.update(item)">{{::L.Buttons.Mod}}</button>
        </td>
      </tr>
    </tbody>
  </table>
</div>
$tq(function(module){
  module.value('Page.SimpleUserInfoManagement.Locale', {
    Title: '간단한 고객정보 관리',
    TableHeaders: {
      Id: '번호',
      FullName: '이름',
      Age: '나이',
      BirthDay: '생년월일'
    },
    Buttons: {
      Reg: '등록',
      Del: '삭제',
      Mod: '수정'
    },
    Modal: {
      TitleNew: '신등등록',
      TitleMod: '수정'
    }
  }); 
})(angular.module('Page.SimpleUserInfoManagement.Locale', []));
<div class="modal-header">
  <form name="frmAddNew" ng-submit="evt.submit()">
    <div class="bodal-header">
      <h3 class="modal-title">{{::L.Modal.TitleNew}}</h3>
    </div>
    <div class="modal-body">
      <div class="form-group">
        <label class="control-label">{{::L.TableHeaders.FullName}}</label>
        <div>
          <input class="form-control" ng-model="ctrl.item.FullName" required>
        </div>
      </div>
      <div class="form-group">
        <label class="control-label">{{::L.TableHeaders.Age}}</label>
        <div>
          <input type="number" class="form-control" ng-model="ctrl.item.Age" required>
        </div>
      </div>
      <div class="form-group">
        <label class="control-label">{{::L.TableHeaders.BirthDay}}</label>
        <div>
          <input class="form-control" ng-model="ctrl.item.BirthDay" required>
        </div>
      </div>
    </div>
    <div class="modal-footer">
      <button type="submit" class="btn btn-success">{{::L.Buttons.Reg}}</button>
    </div>
  </form>
</div>
<div class="modal-header">
  <form name="frmAddNew" ng-submit="evt.submit()">
    <div class="bodal-header">
      <h3 class="modal-title">{{::L.Modal.TitleMod}}</h3>
    </div>
    <div class="modal-body">
      <div class="form-group">
        <label class="control-label">{{::L.TableHeaders.FullName}}</label>
        <div>
          <input class="form-control" ng-model="ctrl.item.FullName" required>
        </div>
      </div>
      <div class="form-group">
        <label class="control-label">{{::L.TableHeaders.Age}}</label>
        <div>
          <input type="number" class="form-control" ng-model="ctrl.item.Age" required>
        </div>
      </div>
      <div class="form-group">
        <label class="control-label">{{::L.TableHeaders.BirthDay}}</label>
        <div>
          <input class="form-control" ng-model="ctrl.item.BirthDay" required>
        </div>
      </div>
    </div>
    <div class="modal-footer">
      <button type="submit" class="btn btn-success">{{::L.Buttons.Reg}}</button>
    </div>
  </form>
</div>