1. 사용자 정의 directive 만들기

  • 제목 만들기
<todo-title></todo-title>
//app.directive('태그명', function(){}))
app.directive('todoTitle', function(){
    return{
        template: '<h1>todo 만들기</h1>'
    }
})
  • item 만들기
<ol class="list-unstyled">
    <li ng-repeat="todo in todos | filter:statusFilter">

    <!--directive 만들기-->
    <todo-item></todo-item>
    <!--
    <date>날짜: </date>
    <div class="input-group mb-3">
        <div class="input-group-text">
        	<input class="form-check-input mt-0" type="checkbox" value="" aria-label="Checkbox for following text input" ng-model="todo.complete">
        </div>
    <input type="text" class="form-control" aria-label="Text input with checkbox" ng-model="todo.title">
    <button class="btn btn-danger" type="button" id="button-addon2" ng-click="remove(todo)">삭제</button>
    </div>
    -->
    </li>
</ol>
app.directive('todoItem',function(){
    return{
        template:
        '<date>날짜: </date>' +
        '<div class="input-group mb-3">' +
        '<div class="input-group-text">' +
        '<input class="form-check-input mt-0" type="checkbox" value="" aria-label="Checkbox for following text input" ng-model="todo.complete">' +
        '</div>' +
        '<input type="text" class="form-control" aria-label="Text input with checkbox" ng-model="todo.title">' +
        '<button class="btn btn-danger" type="button" id="button-addon2" ng-click="remove(todo)">삭제</button>' +
        '</div>'
    }
})
  • template 내용이 길 때는 templateUrl로 대체 가능
app.directive('todoItem',function(){
    return{
        templateUrl: 'todoItem.tpl.html'
    }
})
<!--todoItem.tpl.html-->
<date>날짜: </date>
<div class="input-group mb-3">
  <div class="input-group-text">
    <input class="form-check-input mt-0" type="checkbox" value="" aria-label="Checkbox for following text input" ng-model="todo.complete">
  </div>
  <input type="text" class="form-control" aria-label="Text input with checkbox" ng-model="todo.title">
  <button class="btn btn-danger" type="button" id="button-addon2" ng-click="remove(todo)">삭제</button>
</div>
  • directive 파일 분할하기
//directive.js
import angular from 'angular';

//기존 app 변수 대신 angular.module을 사용
angular.module('todo').directive('todoTitle', function(){
  return{
    template: '<h1>todo 만들기</h1>'
  }
});

angular.module('todo').directive('todoItem',function(){
  return{
    templateUrl: 'todoItem.tpl.html'
  }
});

<script src="lib/directives.js"></script>

-> controller도 같은 방식으로 분할 가능

  • 최종
//app.js
import angular from 'angular';

angular.module('todo',[]); //todo라는 모듈을 정의
//controller.js
import angular from 'angular';

angular.module('todo').controller('TodoCtrl', ['$scope', function($scope){   
  //todo 객체 배열로 만들기
  $scope.todos = [
    {
      title: '요가수련',
      complete: false,
      createdAt: Date.now()
    },
    {
      title: '앵귤러 학습',
      complete: false,
      createdAt: Date.now()
    },
    {
      title: '운동',
      complete: true,
      createdAt: Date.now()
    }      
  ]

  //버튼에 ng-click 추가 후 핸들러 등록
  $scope.remove = function(todo){
    //todos 객체에서 todo의 index 찾기
    var idx = $scope.todos.findIndex(function(item){
      return item.id === todo.id;
    })

    //index찾았으면 해당 index의 todo 제거
    if(idx > -1){
      $scope.todos.splice(idx, 1);
    }
  };

  //추가 폼 동작 구현
  $scope.add = function(newTodoTitle){
    //newTodo 객체 만들기
    var newTodo = {
      title: newTodoTitle,
      complete: false,
      createdAt: Date.now()        
    };

    //newTodo 객체를 배열에 추가하기
    $scope.todos.push(newTodo);

    //input 태그 값 비워주기
    $scope.newTodoTitle = "";
  };
}]);
//directies.js
import angular from 'angular';

//기존 app 변수 대신 angular.module을 사용
angular.module('todo').directive('todoTitle', function(){
  return{
    template: '<h1>todo 만들기</h1>'
  }
});

angular.module('todo').directive('todoItem',function(){
  return{
    templateUrl: 'todoItem.tpl.html'
  }
});

angular.module('todo').directive('todoFilters',function(){
  return{
    templateUrl: 'todoFilters.tpl.html'
  }
});

angular.module('todo').directive('todoForm',function(){
  return{
    templateUrl: 'todoForm.tpl.html'
  }
});
<!-- index.html -->
<!DOCTYPE html>

<html>
  <head>
    <link rel="stylesheet" href="lib/style.css" />

    <script src="lib/app.js"></script>
    <script src="lib/controller.js"></script>
    <script src="lib/directives.js"></script>

    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css"/>
  </head>

  <body ng-app="todo" ng-controller="TodoCtrl">
    <div id="test" class="container">
 
      <!--directive 만들기-->
      <todo-title></todo-title><br>
      <todo-form></todo-form><br>
      
      <ol class="list-unstyled">
        <li ng-repeat="todo in todos | filter:statusFilter">
          
          <!--directive 만들기-->
          <todo-item></todo-item>

        </li>
      </ol>

      <todo-filters></todo-filters>
      
    </div>
    
  </body>
</html>
<!--todoFilters.tpl.html-->
<button class="btn btn-primary" ng-click="statusFilter={}">전체</button>
<button class="btn btn-primary" ng-click="statusFilter={complete:true}">완료</button>
<button class="btn btn-primary" ng-click="statusFilter={complete:false}">미완료</button>
<!--todoForm.tpl.html-->
<form name="todoForm" ng-submit="add(newTodoTitle)">
  <div class="input-group">
    <input type="text"class="form-control" ng-model="newTodoTitle" placeholder="새로운 할 일을 입력하세요." minlength="3">
    <span class="input-group-btn">
      <button class="btn btn-success" type="submit">추가</button>
    </span>
  </div>
  <!--ng-show를 이용해 경고 문구 보이기/숨기기-->
  <div ng-show="todoForm.$dirty && todoForm.$invalid">
      <div class="alert alert-warning" role="alert">3글자 이상 입력하세요.</div>
  </div>
</form>
<!--todoItem.tpl.html-->
<date>날짜: </date>
<div class="input-group mb-3">
  <div class="input-group-text">
    <input class="form-check-input mt-0" type="checkbox" value="" aria-label="Checkbox for following text input" ng-model="todo.complete">
  </div>
  <input type="text" class="form-control" aria-label="Text input with checkbox" ng-model="todo.title">
  <button class="btn btn-danger" type="button" id="button-addon2" ng-click="remove(todo)">삭제</button>
</div>

참고

  • https://www.youtube.com/watch?v=EklH54kysps&list=PLs_XsVQJKaBk_JN5RctLmmVrGwEzpzqaj