AngularJS_codeLab 챕터5
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