본문 바로가기

AngularJS

12. MVC - 모델, 뷰, 컨트롤러

1. 개요

- 지금까지 웹 어플리케이션을 개발할 때 제이쿼리와 같은 AJAX라이브러리와 jQuery-UI 같은 UI 컴포넌트만 있으면 된다고 생각했다 

하지만 문제는 수많은 콜백(callback) 함수와 UI 컴포넌트 조작 코드가 뒤섞여 실제 어플리케이션의 구조화된 코드는 어디서든 찾아 볼 수 없는 스파게티 코드가 되었다.


근래에 들어 이러한 스파게티처럼 제 역할을 찾지 못하고 꼬인 코드를 풀기 위해 많은 자바스크립트 코드가 쏟아져 나왔다.

특히 아키텍처 패턴인 MVC 패턴을 구현한 수많으 자바스크립트 MVC 프레임워크가 그러하다.


AngularJS도 자바스크립트 MVC 프레임워크 중 하나다. 하지만 버전이 올라가며 다양한 기능이 추가됨에 따라 MVVM에 가까게 되었고 사용자들간에 MVVM프레임워크라는 주장이 다분했다.

그런데 AngularJS 팀에서는 AngularJS를 어느패턴으로도 분류하지 않고 사용하는 사람 마은대로 정하라는 의미에서 MVW(Model-View-Whatever)프레임워크라 칭하였다


 1) MVC 패턴 요소별로 설명한다면 아래와 같다.


             

<MVC 요소별 상호관계>                                                                     <어플리케이션 구성 요소별 MVC>

 - MVC 패턴에서 부분별 역할

① 모델(Model) : 도메인에 해당하는 정보를 나타내는 오브젝트다. 대체로 어플리케이션의 데이터(Property)와 행위(Method)를 포함하고 있다.

② 뷰(View) : 모델의 정보를 UI에서 보여주는 역할을 한다. 하나의 모델을 다양한 뷰에서 사용할 수도 있고, 여러 모델을 하나의 뷰에서 사용할 수도 있다.

③ 컨트롤러(Controller) : 어플리케이션에서 사용자의 입력을 받아 모델에 변경된 상태를 반영한다. 이는 모델이 변하게 하여 결국 뷰를 갱신하게 한다.

컨트롤러는 직접 뷰를 변경하는 것이 아니라 주요 로직이 모델을 변경하고 그 결과가 뷰로 나타나는 것이다.


 - MVC 패턴의 장점

① 사용자 인터페이스와 비즈니스 데이터를 분리할 수 있다. 따라서 비즈니스 데이터에 해당하는 모델을 다른 부에서도 사용하여 모델을 재 사용할 수 있다.

② MVC 패턴으로 개발함으로써 팀 사이에 표준화된 개발 방식을 제공한다. 이는 제각기 개발하기 쉬운 자바스크립트 개발 환경에서 표준화된 개발 환경을 제시하는 이점을 준다.


2) MVW 프레임워크 AngularJS의 모델, 뷰, 컨트롤러 설명

 ① 모델 : AngularJS에서는 사용자 정보, 도서 정보, 북마크 정보처럼 하나의 엔터티(Entity)나 여러개의 엔터티가 모델이 된다.

또한 순수자바스크립트 객체가 모델이 되며 이러한 모델 객체는 AngularJS의 $scope 객체로부터 접근할 수 있어야한다.


 - 모델은 컨트롤러에서 $scope 객체에 선언하거나 템플릿에서 선언할 수 있다.

$scope 객체에 선언(컨트롤러 선언)

angular.module('app', []).controller('mainCtrl', function($scope){

$scope.userId : "kshmc";

$scope.bookmark : {name: "구글", url: "www.google.com", image: "google.png"};

$scope.bookmarkList : {[name: "구글", url: "www.google.com", image: "google.png"], [name: "네이버", url: "www.naver.com", image: "naver.png"]};

});

- 위 코드에서 보듯이 컨트롤러에서(자바스크립트에서) 모델을 선언하고 있다.

$scope의 속성명은 모델명을 나타내고 모델이 된다.

여기서 모델은 단순한 문자열이 될 수 도 있고 객체나 배열이 될수도 있다. 즉, 모델은 평범한 자바스크립트 객체(Plain Old JavaScript Object)이다.


 ⓑ HTML 템플릿에서 모델 선언

<div ng-init="userId='kshmc' ; bookmark={name : '구글', url : 'www.google.com', image : 'google.png'}">

<p>{{userId}}, {{bookmark}}</p>

<button ng-click="userEmail='kshmc85@gmail.com' ">Email 추가</button>

</div>

- 위 코드에서 ng-init 지시자에서 userId에 "kshmc"라는 값을 대입함으로써 모델을 선언하였다.

그리고 ng-click에서 대입연산자를 표현식에서 사용하여 userEmail 모델을 만들었다. 이렇게 HTML 템플릿에서 표현식에 대입연산자를 이용함으로써 직접 모델을 선언할 수 있다.


ⓒ 간적접으로 모델 생성

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

<ul>

<li ng-repeat="bookmark in bookmarkList">

<p><a href="{{bookmark.href}}">{{bookmark.name}}</a></p>

</li>

</ul>

 - 위 코드를 보면 <input> 태그에서 ng-model 속성에 search 값을 대입했다. 

AngularJS에서는 ng-model 지시자를 사용하면 해당 모델이 $scope에 없을 경우 암묵적으로 $scope에 search 속성을 만들고 <input>태그의 값을 search 속성의 값으로 대입한다.

즉, 모델을 만들고 데이터를 연결하는 것이다. 

또한 ng-repeat 지시자에서도 모델을 만들게 되는데 bookmarkList 배열 요소의 개수만큼 DOM을 생성하면서 해당 DOM과 연결된 $scope를 만든다. 그리고 해당 $scope에 모델을 추가한다. (bookmark 모델)


② 뷰 : AngularJS에서 뷰는 문서 객체 모델(Document Object Model) 이다. 

브라우저에서 HTML 문서를 읽어서 DOM을 생성하는데 AngularJS에서는 이 DOM이 뷰가 되는 것이다.

- 템플릿과 뷰의 차이점

 ⓐ AngularJS에서는 HTML 문서가 템플릿이다.

 ⓑ 템플릿을 AngularJS가 읽어서 뷰를 생성한다.


- 뷰를 생성하는 과정

ⓐ HTML로 작성한 템플릿을 브라우저가 읽는다.

ⓑ 브라우저는 문서 객체 모델(DOM)을 생성한다.

ⓒ <script src="angular.js">가 실행되어 AngularJS 소스가 실행된다.

ⓓ DOM 생성 시 DOM Content Loaded 이벤트가 발생하는데 AngularJS가 이때 생성된 정적 DOM을 읽고 뷰를 컴파일한다.

컴파일 시 확장 태그나 속성을 읽고 처리한 후 데이터를 바인딩한다.

ⓔ 컴파일을 완료하면 동적 DOM, 즉 뷰가 생성된다.

- 이렇게 생성한 뷰를 사용자가 브라우저에서 보게 되는 것이다.


 - AngularJS가 뷰를 생성하는 과정



③ 컨트롤러 : AngularJS에서 컨트롤러는 어플리케이션의 로직을 담당한다.

 이를 다르게 설명하면 컨트롤러는 모델의 상태를 정의, 변경한다고 할 수 있다. 

 결국 $scope 객체에 데이터나 행위를 선언하는 것이다.


◈ 초기 모델의 상태를 정의하는 컨트롤러 함수


◈ 템플릿에서 ng-controller 지시자를 이용해 템플릿에서 사용


◈ 컨트롤러에서 행위를 정의


◈ 컨트롤러 작성시 주의 사항

 ⓐ 컨트롤러는 단 하나의 뷰에 해당하는 어플리케이션 비즈니스 로직을 담당해야한다.

  컨트롤러에서는 DOM을 조작하면 안된다.


 - AngularJS는 하나의 화면에 여러 컨트롤러를 작성할 수 있다. 하나의 화면은 사실 여러 뷰의 조합으로 이뤄질 수 있기 때문이다.

 이렇게 여러 뷰가 있다면 하나의 컨트롤러를 하나의 뷰와 연결하는 것을 권장한다.