AngularJS 모듈 및 컨트롤러

AngularJS에는 “모듈"이라는 객체를 만들어, 그 안에 ‘컨트롤러’라고 것을 만든다. AngularJS 이용의 가장 기본이 되는 이 두 개체의 생성 및 이용에 대해 설명한다.

모듈 및 컨트롤러 정의

앞에서는 AngularJS를 사용했지만 이전 예제에는 JavaScript 스크립트가 없었다. 역시 본격적인 처리를 구현하려고 되면 “스크립트를 어떻게 조합하는지"가 중요하다.

모듈

AngularJS에는 “모듈"이라는 것을 사용하여 스크립트를 결합한다. 모듈이라는 것은 AngularJS에서 사용되는 “프로그램의 모음” 같은 것이다. AngularJS에는 프로그램은 모듈 단위로 결합한다. 모듈 안에는 몇 개의 작은 프로그램을 결합해 둘 수 있다.

AngularJS에는 ng-app라는 속성을 지정하여, 해당 태그에 AngularJS의 기능을 할당할 수 있었다. 이 ng-app를 사용하면, 모듈 이름을 지정할 수 있도록 되어 있다. 예를 들어,

<body ng-app="hoge">

이런 식으로 하면, 이 <body> 태그에 hoge 모듈의 기능을 사용할 수 있게 된다.

컨트롤러

모듈은 프로그램이 정리된 것이지만, 그 자체로 직접 뭔가 처리가 포함되는 것은 아니다. 일반적으로 이 모듈에 “컨트롤러(controller)“라는 것을 만든다.

컨트롤러는 다양한 작업 및 값을 정리한 객체이다. 이 컨트롤러에 메소드와 속성을 만들어 가는 것이 “AngularJS의 프로그램 작성"하는 거라고 할 수 있다. 모듈에 이 컨트롤러를 필요한 만큼 얼마든지 보관할 수 있다.

컨트롤러의 이용도 모듈과 같이 태그에 컨트롤러 지정을 작성한다. 이것은 ng-controller라는 속성을 사용한다.

<○○ ng-controller="컨트롤러 이름">

이것으로 이 <○○> 태그 내부에 지정한 컨트롤러를 사용할 수 있다. 모듈에는 여러 컨트롤러도 둘 수 있으므로, 필요에 따라 “이 부분에서는 A 컨트롤러"와 같이 사용 범위를 바꾸면서 사용할 수 있다. 물론 여러 컨트롤러를 동시에 사용할 수도 있다.

모듈 및 컨트롤러. 이 두 가지가 무엇인지를 이해하는 것이 AngularJS 개발의 첫 걸음이다.

모듈 및 컨트롤러 생성 및 사용

모듈 및 컨트롤러에 대한 간단한 예제를 만들어 사용하는 방법에 대해 설명한다.

우선은 HTML 파일을 만들어 보자. 아래에 간단한 예제는 아래와 같다.

<!DOCTYPE html>
<html>
<head>
    <title>AngularJS Sample</title>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
    <script src="script.js"></script>
    <style>
    body { color:gray; }
    h1 { font-size:18pt; font-weight:bold; }
    span.label { display:inline-block;width:50px; color:red; }
    input { width:100px; }
    .msg { font-size:14pt; font-weight:bold;color:gray; }
    </style>
</head>
<body ng-app="myapp" ng-init="num = 1000">
    <h1>세금 계산</h1>
    <p>금액을 입력하십시오.</p>
    <div ng-controller="HeloController as ctl">
    <div class="input">
        <span class="label">tax:</span>
        <input type="text" ng-model="ctl.tax">    </div>
    <div class="input">
        <span class="label">price:</span>
        <input type="text" ng-model="num">    </div>
    <p class="msg">세금 포함 : {{ctl.calcWithTax(num)}}원</p>
    <p class="msg">부가세 제외 : {{ctl.calcWithoutTax(num)}}원</p>
    </div>
</body>
</html>

여기에서는 <script src="script.js"></script>라는 형태로 스크립트 파일을 로드하고 있다. 이 script.js라는 파일이 AngularJS의 본체 프로그램이다.

일반적으로 JavaScript 프로그램이라는 것은 HTML 파일에 직접 삽입하여 작성하거나, 별도의 스크립트 파일을 만들어 그것을 로드하여 가져온다. AngularJS에도 어떤 방식으로도 프로그램을 만들 수 있다.

하지만 MVC 아키텍처를 중시하고 화면 표시와 처리의 분리를 생각한다면, HTML 안에서 그대로 JavaScript 코드를 작성하는 것은 그다지 좋은 방법은 아닐 것이다. 여기처럼 다른 파일로 구분하여 거기에 컨트롤러를 작성하는 것이 자연스럽다.

컨트롤러 사용

여기에서는 먼저 다음과 같이하고 “myapp"라는 모듈을 이용하고 있다.

<body ng-app="myapp" ng-init="num = 1000">

이렇게 하여 myapp 모듈에 있는 컨트롤러를 사용할 수 있다. 여기에서는 다음과 같이 컨트롤러를 이용하고 있다.

<div ng-controller="HeloController as ctl">

myapp 모듈에는 “HeloController"라는 컨트롤러를 준비되어 있다. 그런데 이는 조금 이름이 너무 길다. “as"은 컨트롤러에 별칭(alias)으로 줄 수 있다. 여기서 지정한 HeloController as ctl라고 하면 “ctl"라는 이름으로 HeloController을 사용할 수 있게 된다.

<input type="text" ng-model="ctl.tax"><input type="text" ng-model="num">

입력 필드의 <input> 태그에는 ng-model으로 모델을 지정한다. num은 <body> 태그에 ng-init="num = 1000"라는 형태로 초기화되어 있는 값이다.

ctl.tax는 컨트롤러에 있는 값이다. `ctl(HeloController) 안에 있는 “tax"라는 속성을 모델로 설정되어 있는 것이다.

<p class="msg">세금 : {{ctl.calcWithTax(num)}}원</p>
<p class="msg">부가세 제외 : {{ctl.calcWithoutTax(num)}}원</p>

이후 이와 같이 작성되어 있다. 이것은 각각 HeloController에 있는 “calcWithTax”, “calcWithoutTax ‘라는 메소드 값을 작성한 것이다. 컨트롤러에 있는 처리(메소드)는 이런 식으로 호출할 수 있다.

스크립트 생성

이번에는 예제에서 사용하는 스크립트를 작성한다. 아래에 그 예제 코드를 올려 두었다. “script.js"라는 파일 이름으로 HTML 파일과 같은 위치에 배치한다.

angular.module('myapp',[])
    .controller('HeloController',
        function(){
            this.tax = 8;
             
            this.calcWithTax = function(val){
                return Math.floor(val * (100 + this.tax * 1) / 100);
            };
             
            this.calcWithoutTax = function(val){
                return Math.floor(val / (100 + this.tax * 1) * 100);
            };
        }
    );

이번 예제는 앞전에 만든 소비세 계산을 수정한 것이다. tax과 price라는 두 개의 입력 필드가 있었다. 여기에 각각 세율(%) 및 금액을 기입하면 실시간으로 그 세금 포함 가격과 세금 가격을 계산하여 표시하는 연산이 여기에 포함되어 있다.

모듈 생성

angular.module(이름, 배열);

모듈의 작성은 angular 라는 객체의 module 메소드를 사용해 실행한다. angular라는 객체는 AngularJS의 기본이 되는 객체이다. AngularJS의 기능은 모든 이 angular 객체에 정리되어 있다.

module 메서드는 첫번째 인수에 모듈 이름의 텍스트를 지정한다. 두번째 인수에는 이 모듈이 참조하는 다른 모듈을 배열에 정리해 지정한다. 특별히 참조하는 것이 없다면 빈 배열로 둔다.

또한, 여기에서는 특별히 사용하지 않았지만, module 메소드는 생성된 모듈 객체를 반환 값으로 반환한다.

컨트롤러 생성

모듈.controller(이름, 함수);

컨트롤러는 module에서 만든 모듈에 있는 “controller"메소드로 작성한다. 첫번째 인수는 컨트롤러의 이름을 지정한다.

두번째 인수가 문제이다. 여기에 컨트롤러에 결합 구현 부분이 포함된다. “함수"라고 되어 있는데, 이것은 컨트롤러의 “생성자 함수"가 된다.

생성자 함수라는 것은 JavaScript에서 객체를 생성하는데 이용되는 것이다. 여기서 속성과 메소드를 정의하면 된다.

모듈 형태

이번에는 앞에서 작성한 예제 코드를 살펴 보자. 이번 샘플은 다음과 같은 형태로 되어 있다.

angular.module('myapp',[])
    .controller('HeloController',
        function() {
            ...중략...
        }
    }
);

angular.module에는 모듈 myapp를 만들고, controller를 호출하여 HeloController을 정의하고 있다. 생성자 함수 내에는 tax 속성과 calcWithTax, calcWithoutTax의 두 가지 메소드르 제공하고 있다.

이런 식으로 “모듈 생성”, “컨트롤러 생성”, “생성자 함수에서 필요한 값과 처리 구현"하는 것이 모듈 및 컨트롤러 사용의 기본이다.

생성자 함수

컨트롤러에 준비되어 있는 “생성자 함수"를 어떻게 만들지가 AngularJS 이용의 핵심이다.

생성자 함수는 JavaScript의 객체를 생성하는 함수이다. 이것은 객체에 제공하는 속성과 메소드를 내부에서 정의해야 한다.

function(){
    this.○○ = ☓☓; // 속성 정의
    this.△△ = function(){...} // 메소드 정의
}

생성자는 속성과 메소드(알기 쉽게 말하면, 값을 저장 변수로 처리를 구현하는 함수)를 그 내부에서 정의한다. 이것은 “this. ○○"와 같이 this 내에 속성에 대입하는 형태로 작성한다.

this는 생성자 함수에 의해 생성되는 객체 자신이다. 이렇게 하여 객체 자체의 속성에 값을 할당하여 객체의 내용을 만들어 간다. 생성자 함수는 AngularJS에 한정되지 않고, JavaScript 전반에서 사용되는 기술이다.

간단한 데이터베이스 생성

이번에는 데이터를 다루는 예제를 만들어 보자. 컨트롤러에는 배열로 데이터를 보관해 두었다가 거기서 데이터를 얻어와서 표시하는 것이다. 아무튼, 간단한 데이터베이스를 사용하는 경우의 예제이다.

HTML 화면 표시

먼저, HTML 파일을 만든다. 아래 예제 코드를 올려 두었다. 아래와 같이 작성하여 저장한다.

<!DOCTYPE html>
<html>
<head>
    <title>AngularJS Sample</title>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
    <script src="script.js"></script>
    <style>
    body { color:gray; }
    h1 { font-size:18pt; font-weight:bold; }
    span.label { display:inline-block;width:50px; color:red; }
    input { width:100px; }
    .msg { font-size:14pt; font-weight:bold;color:gray; }
    </style>
</head>
<body ng-app="myapp" ng-init="num=0">
    <h1>데이터 표시</h1>
    <p>ID번호를 입력해 주세요.</p>
    <div ng-controller="HeloController as ctl">
    <div class="input">
        <span class="label">ID:</span>
        <input type="text" ng-model="num">
        <button ng-click="ctl.doAction(num)">click</button>
    </div>
    <p class="msg">{{ctl.getData()} }</p>
    </div>
</body>
</html>

여기에서는 3개 곳에 AngularJS의 기능이 사용되고 있다. 간단하게 정리하면 아래와 같다.

myapp 모듈 설정

<body ng-app="myapp" ng-init="num = 0">

먼저 <body>에 myapp 모듈을 설정한다. 그리고 num이라는 변수를 초기화한다. 이것으로 <body>에서 myapp 모듈의 기능을 사용할 수 있게 되었다.

num 설정

<input type="text" ng-model="num">

준비한 변수 num은 여기에서 사용하고 있다. 입력 필드의 값을 관리하는 모델로 num을 설정한다. 이것으로 입력된 값이 num에 항상 보관되게 된다.

getData 데이터 표시

<p class="msg">{{ctl.getData()}}</p>

이것이 데이터를 꺼내 표시하는 부분이다. HeloController의 “getData"라는 메소드를 호출한다. 이 메소드는 현재 입력된 번호의 데이터를 텍스트로 반환한다. 이것으로 필요한 데이터가 언제든지 여기에 표시된다.

클릭시 동작 설정

<button ng-click="ctl.doAction(num)">click</button>

이번에 새롭게 등장한 속성이 “ng-click"이다. 이것은 onclick 속성에 해당되는 것으로, 클릭했을 때 처리를 실행시키는 것이다. <p class="msg">에 설정되어 있는 {{ctl.getData()}}이 실시간으로 표시가 업데이트 되지만, 때로는 “클릭하면 작업 실행"하는 방식도 필요할 것이다.

모듈 및 컨트롤러 정의

스크립트를 작성한다. 아래에 예제는 아래와 같다. 파일명은 script.js으로 저장한다.

var myapp = angular.module('myapp',[]);
myapp.controller('HeloController',
    function(){
        this.count = 0;
        this.data = [
            [0,'nobody','nodata...'],
            [1,'성진','sungjin@foryou'],
            [2,'원석','wonsuck@flower'],
            [3,'병호','byeongho@devkuma.com']            
        ];
        this.getData = function(){
            return this.data[this.count][0] + ': ' + 
                this.data[this.count][1] + ', ' + 
                this.data[this.count][2] + '.';
        };
        this.doAction = function(num){
            this.count = num;
        }
    }
);

작성되면 접속해 본다. 입력 필드에 1 ~ 3의 번호를 입력하면 해당 번호의 데이터가 표시된다. 데이터를 저장하고 있는 data 속성의 내용을 추가하면 더 많은 데이터를 처리할 수 있다.

이번에는 module 메소드로 모듈을 만든 것을 변수에 대입하고, 그 변수에서 controller 메소드를 호출하도록 되어 있다. 뭐, 어떻게 작성하여도 상관은 없지만, 모듈에 여러 컨트롤러를 지정해야 하는 경우는 이렇게 변수로 만들어 작성하는 것이 편하다.

여기에서는 this.data에 배열로 데이터를 저장하고 있다. 이것은 2차원 배열이고, ID 번호, 이름, 이메일 주소 등의 값이 저장되어 있다. getData 메소드는 count 속성에 설정된 인덱스 번호의 데이터를 꺼내 텍스트에 만들어 return한다.

ng-click으로 실행 시키려면?

이번에는 getData 외에 “doAction"이라는 메소드도 만들었다. 이 메소드는 ng-click으로 호출되면 처리된다.

여기서에서 수행하고 있는 것은 인수에 num을 count 속성에 설정하는 단순히 처리이다. 이 처리로 count 값이 변경되면, 템플릿에 {{ctl.getData()}}를 지정되어 있는 표시가 즉시 업데이트되어 변경한 데이터로 바뀐다.

표시 부분은 AngularJS가 자동으로 업데이트되기 때문에 액션 메소드는 단순히 설정을 저장하고 있는 값을 재 작성만하면 된다. 보통 JavaScript의 액션 처리와는 상당히 다른 느낌이다는 것을 알 수 있다.




최종 수정 : 2017-12-27