[AngularJS] AngularJS 학습 (1)

2019. 4. 3. 18:37Frontend/AngularJS

반응형
AngularJS

해당 포스트는 Inflearn AngularJS 강좌를 기반으로 작성되었으며, 언급되는 개념 및 실습 과정을 담았습니다.
따라서, 코드는 단계적으로 작성되어 이전 코드와 연결되어 있습니다.

AngularJS

1. AngularJS 개념

공식 페이지의 Coceptual Overview를 보면 개념들이 정의되어 있다.

  1. Directives : 확장된 HTML로, custom 속성elements를 뜻함

    • directives를 사용해 직접 태그를 정의할 수 있다.

  2. Expressions : HTML에서 JS의 데이터를 출력해야 하는 경우 사용

1.// html
2.
3.<!--{{ name }}` 부분에 지정한 데이터가 삽입됨-->
4.<p>hello {{ name }}</p>
  1. Module

    • 기능적으로 비슷한 것들을 모아 모듈을 만듦.

    • 의존관계가 있을 경우 다른 모듈을 주입해서 사용 가능

  2. Controller

    • HTML 뒷 단에 위치.

    • HTML View를 조작함.

    • View의 비즈니스 로직을 구현하는데만 사용해야 한다.

  3. Service

    • (Controller와 다르게) 재 사용할 수 있는 비즈니스 로직

    • 싱글톤으로 구현되어 있음

    • 어플리케이션 데이터를 다루는데 사용

참고

@AngularJS 전체 구성 요소

AngularJS 전체 구성 요소

@AngularJS 흐름

AngularJS 흐름

개발 환경 구성

강의는 Plunker를 사용해서 개발하지만, 나는 Codepen을 사용해서 개발할 예정

2. Controller

index.html로 시작하기

  • ng-app

    • 선언하는 부분부터 앵귤러를 사용하겠다고 알려주는 역할

    • 앵귤러 쪽에서는 angular Directive를 찾아 해석함

  • ng-init

    • 변수나 함수를 초기화 함

  • expression 식({{ }} 기호)을 사용해 표현

index.html

1.<html>
2. <head>
3. <!-- bootstrap -->
4. <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
5. <!-- angularjs -->
6. <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
7. </head>
8.
9. <body ng-app ng-init="name = 'mizzo'">
10. <h1>Hello {{ name }}!</h1>
11. </body>
12.</html>

실행결과

alt text

module & controller & 출력하기

  • 모듈

    • 하나의 큰 컨테이너 (컨트롤러, 액티브, 서비스 등 포함)

  • 컨테이너

    • View의 비즈니스 로직을 구현하는데 사용

  • $scope : controller와 html간의 연결고리 역할

script.js

1.(function() {
2. // 배열을 파라미터로 받는 todo라는 angular module을 생성해준다.
3. var app = angular.module('todo', []);
4.
5. // 컨트롤러를 todo라는 모듈 안에 생성해야 한다. -> app.controller
6.
7. // TodoCtrl라는 이름을 가진 컨트롤러를 생성한다.
8. app.controller('TodoCtrl', ['$scope', function ($scope) {
9. $scope.name = 'mizzo';
10. }]);
11.})();

index.html

1.<html>
2. <head>
3. <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
4. <link rel="stylesheet" href="style.css">
5. </head>
6.
7. <!-- ng-controller로 위에 만든 컨트롤러를 연결한다-->
8. <body ng-app="todo" ng-controller="TodoCtrl">
9. <!-- scope의 name을 표현하자 -->
10. <h1>Hello {{ name }}!</h1>
11.
12.<!-- 습관적으로라도 스크립트는 바디가 끝나기 직전에 호출하자. -->
13. <script src="script.js"></script>
14. </body>
15.</html>

실행결과

alt text

실제 프로젝트에선 object를 주고 받을 것.
todo object를 만들고 표현해보자.

script.js

1.(function() {
2. var app = angular.module('todo', []);
3.
4. app.controller('TodoCtrl', ['$scope', function ($scope) {
5. //object를 만들어 주고 받자
6. $scope.todo = {
7. title: '요가 수련',
8. completed: false,
9. createdAt: Date.now()
10. }
11. }]);
12.})();

index.html

1.<html>
2. <head>
3. <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
4. <link rel="stylesheet" href="style.css">
5. </head>
6.
7. <body ng-app="todo" ng-controller="TodoCtrl">
8. <h1>Todo</h1>
9.
10. <!-- object 그대로를 출력한다. -->
11. {{ todo }}
12.
13. <!-- object 내의 변수를 각각 출력 -->
14. <h3>{{ todo.title }}</h3>
15. <p>{{ todo.completed }}</p>
16. <date>{{ todo.createdAt }}</date>
17. <script src="script.js"></script>
18. </body>
19.</html>

실행 결과

Alt text

엔진모델은 양방형 바인딩이다.
대표적인 예로, input 태그와 ng-model directive를 활용해 변경된 데이터를 js 변수 object에 바인딩할 수 있다.

script.js 파일은 그대로 두고 html만 수정해보자
index.html

1.<html>
2. <head>
3. <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
4. <link rel="stylesheet" href="style.css">
5. </head>
6.
7. <body ng-app="todo" ng-controller="TodoCtrl">
8. <h1>Todo</h1>
9.
10. <!-- todo의 title이 그대로 반영된다. -->
11. <input type="text" ng-model="todo.title">
12. <!-- todo의 completed이 그대로 반영된다. -->
13. <input type="checkbox" ng-model="todo.completed">
14.
15. <!-- todo object 그대로 출력하여 실시간으로 바인딩되는 것을 확인하자 -->
16. {{ todo }}
17. <script src="script.js"></script>
18. </body>
19.</html>

실행 결과

@실시간으로 text와 체크 여부를 변경할 때마다 출력되는 데이터가 달라지는 것을 확인할 수 있다.

실시간으로 text와 체크 여부를 변경할 때마다 출력되는 데이터가 달라지는 것을 확인할 수 있다.

3. 내장 Directive

ng-repeat

  • 배열과 함께 사용하면 좋음

  • 반복문 처럼 사용할 수 있다.

todos라는 배열에 todo object 들을 넣어두고
html에서 ng-repeat을 사용해 불러오자.

script.js

1.var app = angular.module('todo', []);
2.
3.app.controller('TodoCtrl', function($scope) {
4. $scope.todos = [
5. {
6. title: '요가 수업',
7. completed: false,
8. createdAt: Date.now()
9. },
10. {
11. title: '앵귤러 학습',
12. completed: false,
13. createdAt: Date.now()
14. },
15. {
16. title: '운동하기',
17. completed: true,
18. createdAt: Date.now()
19. }
20. ]
21.});

index.html

1.<html>
2. <head>
3. <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
4. <link rel="stylesheet" href="style.css">
5. </head>
6.
7. <body ng-app="todo" ng-controller="TodoCtrl">
8. <h1>Todo</h1>
9.
10. <ul>
11. <!-- todo는 todos 안의 한 object를 가르키는 커서이다. -->
12. <li ng-repeat="todo in todos">
13. <input type="text" ng-model="todo.title">
14. <input type="checkbox" ng-model="todo.completed">
15. <date>{{ todo.createdAt }}</date>
16. </li>
17. </ul>
18.
19. <script src="script.js"></script>
20. </body>
21.</html>

실행 결과

Alt text

Bootstrap 적용해서 더 예쁘게 해보자

  1. components>input-group>checkboxes and radios 적용하기

Alt text

  1. css > typography > unstyled 적용해서 앞에 리스트 점 없애 주기

index.html

1.<html>
2.
3.<head>
4. <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
5. <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
6. <link rel="stylesheet" href="style.css">
7.</head>
8.
9.<body ng-app="todo" ng-controller="TodoCtrl">
10. <h1>Todo</h1>
11.
12. <!-- unstyled 적용 -->
13. <ul class="list-unstyled">
14. <li ng-repeat="todo in todos">
15. <!-- checkboxes-and-radios 적용 -->
16. <div class="input-group mb-3">
17. <div class="input-group-prepend">
18. <div class="input-group-text">
19. <input type="checkbox" ng-model="todo.completed">
20. </div>
21. </div>
22. <input type="text" ng-model="todo.title">
23. </div>
24. <date>{{ todo.createdAt }}</date>
25. </li>
26. </ul>
27.
28. <script src="script.js"></script>
29.</body>
30.
31.</html>

실행 결과

Alt text

ng-filter

  • 표현식을 사용해 일정한 포맷으로 만들어줄 수 있다.

  • 커스텀 필터를 생성해 원하는 값만 필터링 해줄 수 있다.

angularJS의 기본 date filter를 사용해 date를 예쁘게 출력할 것

문서를 보니 html에서는 아래 양식을 사용해서 필터 적용

1.{{ date_expression | date : format : timezone}}

index.html에 date 부분만 아래 코드로 변경한다.
index.html

1.<date>{{ todo.createdAt | date : 'yyyy-MM-dd HH:mm:ss'}}</date>

실행 결과

Alt text

ng-Click

  • button에 추가하여 click 했을 때 실행시킬 함수를 지정할 수 있다.

실습
todo 항목에 삭제 버튼을 추가할 것이다.
부트스트랩 components > input-group > button-addons에 있는 오른쪽 버튼 부분을 가져와 더해주자
그리고 다음과 같이 수정했다.

  • class = btn-danger로 수정해 빨간색 위험한 UI를 표현했다. (기본 설정 값 이용)

  • ng-click = remove()를 지정해 버튼이 클릭 됐을 때 todo모듈의 TodoCtrl 컨트롤러안에 선언한 remove 함수를 호출할 것이다.

index.html

1.<html>
2.
3.<head>
4. <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
5. <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
6. <link rel="stylesheet" href="style.css">
7.</head>
8.
9.<body ng-app="todo" ng-controller="TodoCtrl">
10. <h1>Todo</h1>
11.
12. <ul class="list-unstyled">
13. <li ng-repeat="todo in todos">
14. <div class="input-group mb-3">
15. <div class="input-group-prepend">
16. <div class="input-group-text">
17. <input type="checkbox" ng-model="todo.completed">
18. </div>
19. </div>
20. <input type="text" ng-model="todo.title">
21. <!-- addon 버튼 추가 부분-->
22. <div class="input-group-append">
23. <button class="btn btn-danger" type="button" ng-click="remove()">삭제</button>
24. </div>
25. <!-- -->
26. </div>
27. <date>{{ todo.createdAt | date : 'yyyy-MM-dd HH:mm:ss'}}</date>
28. </li>
29. </ul>
30.
31. <script src="script.js"></script>
32.</body>
33.
34.</html>

버튼이 눌릴 때 호출될 함수를 만들어준다.

  • todo모듈의 TodoCtrl 컨트롤러안에 remove 함수를 선언한다.

  • 간단하게 눌렸는지 확인하기 위해 경고창을 띄워주자.

script.js

1.var app = angular.module('todo', []);
2.
3.app.controller('TodoCtrl', function($scope) {
4. $scope.todos = [
5. {
6. title: '요가 수업',
7. completed: false,
8. createdAt: Date.now()
9. },
10. {
11. title: '앵귤러 학습',
12. completed: false,
13. createdAt: Date.now()
14. },
15. {
16. title: '운동하기',
17. completed: true,
18. createdAt: Date.now()
19. }
20. ];
21.
22. // 매개변수가 없는 remove 함수를 선언한다.
23. $scope.remove = function() {
24. alert();
25. }
26.});

실행결과

@삭제 버튼 눌렀을 때의 화면

삭제 버튼 눌렀을 때의 화면

이제 진짜 버튼이 눌렸을 때 삭제되도록 구현해보자.

  1. id를 비교하여 삭제하고자 하는 객체의 index를 찾는다.

  2. splice함수를 이용해 객체 배열에서 특정 객체를 삭제한다.

script.js

1.var app = angular.module('todo', []);
2.
3.app.controller('TodoCtrl', function($scope) {
4. // 코드 생략
5. ...
6.
7. $scope.remove = function(todo) {
8. // todos 배열에서 todo index를 찾는다.
9. var idx = $scope.todos.findIndex(function (item) {
10. return item.id == todo.id;
11. });
12.
13. // idx가 유효할 때 삭제해준다.
14. if (idx > -1) {
15. // 배열 객체에서 제공되는 함수인 splice를 이용하면 원하는 위치에 요소를 삭제할 수 있다.
16. // idx 위치부터 1개의 요소를 삭제한다.
17. $scope.todos.splice(idx, 1)
18. }
19. }
20.});

실행 결과

@첫번째 삭제 버튼을 눌렀을 때 결과

첫번째 삭제 버튼을 눌렀을 때 결과

Filter Button

버튼을 눌렀을 때 각 조건에 따라 TODO 리스트가 필터링된 결과를 출력하도록 구현해볼 것이다.

이를 구현하기에 앞서,
이전에 배웠던 filter 기능을 사용해 기존 리스트를 필터링할 수 있다.

index.html

1.<!-- completed가 true인 값들만 출력한다. -->
2.<li ng-repeat="todo in todos | filter:{completed : true}">

실행 결과

Alt text

이 기능을 활용해 필터 버튼을 구현할 것인데,
필터에 변수를 지정해두고 케이스별로 다른 값을 넣어주어 필터링 조건을 변경할 것이다.

index.html

1.<html>
2.
3.<head>
4. <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
5. <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
6. <link rel="stylesheet" href="style.css">
7.</head>
8.
9.<body ng-app="todo" ng-controller="TodoCtrl">
10.
11. <!-- 기존 코드를 컨테이너에 담았다. -->
12. <div class="container">
13. <h1>Todo</h1>
14.
15. <ul class="list-unstyled">
16. <!-- statusFilter라는 변수를 지정해주자 -->
17. <li ng-repeat="todo in todos | filter: statusFilter">
18. <div class="input-group mb-3">
19. <div class="input-group-prepend">
20. <div class="input-group-text">
21. <input type="checkbox" ng-model="todo.completed">
22. </div>
23. </div>
24. <input type="text" ng-model="todo.title">
25. <div class="input-group-append">
26. <button class="btn btn-danger" type="button" ng-click="remove(todo)">삭제</button>
27. </div>
28. </div>
29. <date>{{ todo.createdAt | date : 'yyyy-MM-dd HH:mm:ss'}}</date>
30. </li>
31. </ul>
32.
33. <!-- 필터 버튼 선언 부분 -->
34. <!-- ng-click에 statusFilter값을 변경해주는 코드를 넣는다 -->
35. <button class="btn btn-primary" ng-click="statusFilter = {completed : true}">Completed</button>
36. <button class="btn btn-primary" ng-click="statusFilter = {completed : false}">Active</button>
37. <button class="btn btn-primary" ng-click="statusFilter = {}">All</button>
38. </div>
39.
40. <script src="script.js"></script>
41.</body>
42.
43.</html>

실행 결과

completed 버튼 클릭 Active 버튼 클릭 All 버튼 클릭
Alt text Alt text Alt text

참고 사이트

반응형