'AngularJS'에 해당되는 글 2건

  1. 2014.08.19 angularjs - Module
  2. 2014.08.03 angularjs - $scope

Module

이전에 작성했던 예제들은 모두 전역으로 선언한 생성자 및 변수로 실제 애플리케이션에서는 사용을 지양하고있다.
전역으로 선언할 경우 예상치 못한 부분에서 변수의 값이 변경이 될 수 있으며 가독성 및 테스트용이성이 떨어지는 등 코드의 유지보수가 어려워진다.

AngularJS에는 'angular'라는 전역 네임스페이스가 정의되어있으며, 이 네임스페이스는 다양하고 편리한 유틸함수를 제공한다.
그 중 module은 AngularJS가 관리하는 객체(controller, service 등)의 컨테이너 역할을 한다.


Module을 통한 Controller 생성방법 비교

 전역변수 선언방법

Module 생성방법 

 var HelloCtrl = function ($scope) {
     $scope.name = 'World';
 }

 angular.module('hello', [])
    .controller('HelloCtrl', function ($scope) {
        $scope.name = 'World';
    });

  angular.module("모듈이름", [다른모듈과의 의존관계]).controller("컨트롤러 이름", 생성자함수);

모듈을 정의 후 사용하기위해서 ng-app 속성에 값으로 정의하여 AngularJS에 모듈을 등록하여야 한다.



[실행 결과]


[controller생성 - 전역변수]

위의 코드는 앞서 구현해보았던 전역변수를 통한 생성방식이다. 이 코드를 AngularJS의 module을 통한 생성방식으로 변경하면 다음과 같다.


[controller생성 - module]

ng-app 속성의 값으로 해당 화면에서 사용할 모듈이름을 AngularJS에 알려준다.

angular.module 메소드는 모듈을 생성하고, 생성한 모듈을 반환한다.

아래와 같이 모듈생성 후 반환되는 값을 받아서 재사용할 수 있다.
var module = angular.module('module_name', []) ; // module 생성 및 반환

다음과 같이 모듈생성과 생성과 생성된 모듈을 사용하는부분을 분리하여 구현할 수 있다. 
angular.module('module_name', []); // module 생성
var module = angular.module('module_name'); // AngularJS 컨테이너에 module_name 이름으로 등록된 모듈을 얻어온다.

모듈에 여러개의 컨트롤러를 구현하기 위해서는 생성된 모듈을 변수로 가지고 이를 재사용해야한다. module.controller 메소드의 반환값이 module이 아니기때문에 2번째의 컨트롤러 함수 호출을 위해 module을 얻어야한다.

ng-app에는 1개의 모듈만 등록이 가능하다. 그러므로 여러개의 모듈을 사용하고싶다면 여러개의 모듈에 의존성을 갖는 최상위 모듈을 정의 후 의존성 모듈로 여러개의 모듈을 등록하여 사용할 수 있다.
angular.module('module1',[]); // module1 생성
angular.module('module2',[]); // module2 생성
angular.module('app', ['module1', 'module2']); // 최상위 모듈 app 생성 및 module1, module2 dependency 등록
<body ng-app='app'> // ng-app 속성에 최상위모듈 app 등록하면 의존성 모듈로 등록된 module1, module2 모두 사용 가능하다.

만약 module1과 module2에 동일한 이름의 controller를 생성한 경우 dependency에 마지막으로 등록한 module2의 값으로 덮어씌워져 화면에 노출된다.

'development > angularjs' 카테고리의 다른 글

angularjs - $scope  (0) 2014.08.03
angularjs - hello world  (0) 2014.08.03
Posted by dreamhopp
,

모델에 값을 할당하는 방법은 ng-init을 통한 초기화 외에 $scope에 프로퍼티 할당을 통해서도 가능하다.



[ case1. ng-init 디렉티브를 통한 값 할당 ]


[ case2. $scope 프로퍼티 할당을 통한 값 할당 ]

1. ng-init 디렉티브를 제거하고 ng-controller로 컨트롤러의 스코프 이름을 정해준다.
2. script 에서 controller의 이름을 통해 함수를 정의하며 인자로 $scope를 받는다.
3. $scope.name 이라는 프로퍼티에 값 할당을 통해 HelloCtrl 컨트롤러 내부에서만 동작하는 name 변수에 값을 할당 할 수 있다.


스코프 ($scope)

$scope 객체는 프로퍼티 할당을 통해 뷰(템플릿)에게 도메인 모델을 제공한다.
제공하는 도메인 모델은 데이터 뿐만 아니라 뷰에 대한 특정 동작(function)도 추가할 수 있다.
특정 동메인 모델과 동작을 특정 뷰 레이어에 한정시킬 수 있다. (위의 예제에서는 HelloCtrl의 function의 인자로 받은 $scope는 동작이 HelloCtrl 내로 한정된다.)


컨트롤러 (ng-controller)

초기 모델 값을 지정하는 부분은 ng-init 디렉티브와 ng-controller 디렉티브가 동일하게 동작하므로,
ng-controller를 사용하면 초기화 로직을 HTML 템플릿에 넣지 않고 javascript로만 작성이 가능하다.

* ng-controller의 초기화로직

  1. 초기 모델 값 지정
  2. $scope에 UI동작(함수) 추가

$scope 생성의 비밀!

AngularJS에는 $rootScope 라는 모든 스코프의 부모스코프가 있으며, 이 $rootScope 인스턴스는 애플리케이션이 초기화 될 때 만들어진다. AngularJS는 DOM 트리에서 $scope를 생성하는 디렉티브(예: ng-controller)를 만날 때 마다 Scope.$new() 메소드를 호출하여 상위 스코프를 상속받은 새로운 스코프를 생성하여 전달하는 것이다. 이렇게 생성된 스코프는 부모 스코프를 가리키는 $parent 프로퍼티를 갖고 있다. 생성된 스코프는 상위 스코프를 상속받기 때문에 최상위 스코프에 프로퍼티를 정의해둔 경우, 모든 하위 스코프에서 같은 이름으로 해당 프로퍼티 정의 없이 접근이 가능하다.
(설명에 따르자면 ng-init을 통해 AngularJS가 초기화 될 때 $rootScope 인스턴스가 생성된다. $rootScope와 $scope를 java의 최상위 객체인 Object와 String 클래스와의 관계처럼 비슷한 개념으로 이해하면 어떨까 생각한다. Object의 equals, hashCode와 같은 메소드를 상속받은 하위 클래스(String)에서 사용이 가능하듯 말이다.)
다만, $parent 프로퍼티 사용시 HTML 구조를 조금만 변경해도 애플리케이션이 쉽게 망가질 수 있기 때문에 $parent 프로퍼티는 사용하지 않는것을 권장하고있다.



[ $scope의 범위 ]

위의 예제에서 $scope의 상속과 $parent에 대해 이해할 수 있을 것이다.
첫번째, Hello, world! 는 ng-init을 통해 초기화된 name 모델의 값으로 <body>태그에 해당하는 $scope에 저장된 값이다. (이 값이 $rootScope가 아닌 $scope라고 말하는 이유는 HelloCtrl.$scope.$parent를 화면에 출력했을때 노출된 값이 $scope 였기 때문이다. 다만 $rootScope가 아닌지도 명확히 할 수 없는 이유는 HelloCtrl.$scope.$parent.$parent 의 값으로 아무런 값도 출력되지 않았고, <body> 태그에서도 $parent 출력시 아무런 값도 출력되지 않았기때문이다. 마찬가지로 $rootscope, $rootScope 모두 아무런 값도 출력되지 않는다. 아직은 AngularJS에 대해 다 아는것이 아니기때문에 $rootScope의 정체는 차차 밝혀나가야겠다.)
두번째, Hello, world_child! 는 ng-controller를 통해 HelloCtrl 컨트롤러의 $scope로 상위 name 모델을 상속받는다. name 모델의 초기값인 world를 world_child로 변경한 경우 상위값은 변경없이 자신(HelloCtrl 컨트롤러 범위 내)의 스코프 모델 값만 변경되어 반영된 것을 확인할 수 있다.
세번째, Hello, parent's world! 는 HelloCtrl 컨트롤러의 $scope의 상위 스코프($parent)를 가리키며, 이 상위 $parent는 결국 ng-init을 통해 초기화된 name 모델을 가리킨다. HelloCtrl.$scope.name의 값을 변경한 경우, $parent.name과는 다른 네임스페이스에 존재하므로 $parent 에는 영향이 미치지 않으며, $parent.name의 초기값인 world로 노출되는 것이다.



[ ng-repeat : 반복 ]

1. ng-app
  : AngularJS를 초기화한다.($rootScope 생성)
2. ng-controller="WorldCtrl"
  : AngularJS는 DOM 트리 탐색 중 ng-controller 디렉티브를 만나 Scope.$new()를 호출하여 새로운 $scope 인스턴스를 생성한다.
3. ng-repeat="country in countries"
  : ng-repeat은 
컬렉션을 순회하며 컬렉션의 한 요소당 DOM 요소를 하나씩 생성한다.
    ng-repeat은 countries의 요소 마다 <li> 엘리먼트와 $scope를 생성하며, 
    WorldCtrl의 $scope 에 할당된 countries에서 값을 하나씩 빼내어 country라는 이름으로 새롭게 생성된 li태그의 $scope에 추가한다.
4. {{worldPercentage(country.population)}}
  : worldPercentage 메소드는 WorldCtrl controller의 $scope에 정의된 메소드로 하위 li 태그의 $scope에 상속되어 정의없이 사용이 가능하다.
    다만, 
country.$scope에서 메소드가 호출되었지만 메소드 정의시점의 $scope가 WorldCtrl의 $scope였으므로 $scope.population의 값은 7000이 된다. 

    

스코프 생명주기

네임스페이스를 분리하고 변수의 이름 충돌을 피하기 위해 스코프는 꼭 필요하며, 작으면서 계층이 잘 분류된 스코프는 메모리 소모를 관리하기에도 좋다. 한 스코프가 더이상 필요없어지면 스코프에 포함된 모델과 기능도 정리(GC)될 수 있다.
새로운 스코프는 보통 스코프 생성 디렉티브에 의해 생성되기도 하고 정리되기도 한다. 이외에도 $new()와 $destroy() 메소드를 사용하여 스코프를 직접 생성하거나 정리할 수도 있다. (Scope 객체에 선언된 메소드이다.)


 ※ 참고

AngularJS는 유효한 DOM 트리(HTML 태그가 올바르게 열고 닫힌 경우)에서만 동작하며, 유효하지 않은 DOM 트리에서는 동작하지 않고 어떠한 에러 메시지도 나오지 않는다.



** 용어 **

MVVM 패턴 : Model - View - ViewModel 패턴의 약어

ViewModel : View의 이벤트 및 표현을 담당하며, ViewModel의 값이 바뀌면 View에 자동으로 업데이트한다.


참고URL : 

http://atconsole.com/2013/06/05/mvc-mvp-mvvm-%EC%9D%98-%EC%9D%B4%ED%95%B4/

------------------------------------

nodejs와의 차이점

angularjs를 렌더링하기위해서 브라우저의 반응속도가 느려지지 않을까? 느려진다면 얼마만큼 느려질까?


ng-init 디렉티브로는 하나의 모델일때만 초기값을 설정할 수 있는듯하다. 여러개를 선언한 경우 모델로서 동작은 하지만 초기화 값이 화면에 렌더링되어 표현되지 않는다.


javascript에 정의된 이벤트와 angularJS의 이벤트명이 어떻게 맵핑되는걸까? api document에 있나?
(angularjs는 dom 기반의 이벤트 프로그래밍 모델 사용을 지양하고있다. 대신 양방향 데이터 바인딩을 사용할 것을 권장한다.)


$scope API Reference(method, variable)


디렉티브의 종류

ng-disabled

ng-controller

ng-repeat

ng-model

ng-app

ng-init

ng-class

'development > angularjs' 카테고리의 다른 글

angularjs - Module  (0) 2014.08.19
angularjs - hello world  (0) 2014.08.03
Posted by dreamhopp
,