PhoneCat Tutorial App 3 - Static Template & Angular Template

2014. 9. 17. 14:26JS&FRONT/AngularJS

1. Static Template

Angular가 표준 HTML을 어떻게 증진시키는지에 대해 설명하기 위해서는,
여러분들은 순수한 정적 HTML 페이지를 만들고,
이 HTML 코드를 Angular가 어떠한 데이터 셋을 가지고도 같은 결과를 다이나믹하게 보여주는 탬플릿으로
어떻게 변경할 수 있는지에 대해 설명할 것입니다.
이번 단계에서 여러분들은 두 개의 셀룰러 폰에 대한 약간의 기본 정보를 HTML 페이지에 추가할 것입니다.

- 페이지는 현재 두개의 폰에 관한 정보를 가진 리스트를 포함하고 있다.

첫번째 단계 체크아웃 : Git checkout –f step-1

app/index.html


Experiments 

정적인 HTML에 아래 예제 내용을 추가해보세요.

<p> Total number of phone : 2 </p>

Summary

여러분의 어플리케이션에서 이런 추가는 정적인 HTML를 사용하여 리스트를 보여주는데 정적인HTML를 사용하게 됩니다. 

자 같은 리스트를 다이나믹하게 생성하기 위해 AngularJS를 사용하는 방법을 배우러 두번째 단계로 갑시다. XD


2. Angular Templates

AngularJS와 함께 다이나믹한 웹페이지를 만들 시간입니다.
곧 추가할 컨트롤러에 대한 코드를 검증하는 테스트를 추가할 것입니다.
어플리케이션에 코드를 구성하는 많은 방법이 있습니다.
Angular 어플리케이션에는, 코드를 분리하고 관심을 분리하는 MVC 디자인 패턴의 사용을 장려합니다.
그걸 염두에 두고, 모델, 뷰 그리고 컨트롤러 컴포넌트들을 우리 어플리케이션에 추가하기 위해 Angular 와 자바스크립트를 사용해 봅시다.

세 개의 폰 리스트는 데이터로부터 다이나믹하게 현재 생성되어집니다.

두번째 단계 체크아웃 : Git checkout –f step-2

View and Template

Angular 에서, View 는 HTML 템플릿을 통한 Model의 Projection(투사,투영)입니다.
이건 모델이 변경될 때마다 Angular는 View를 업데이트하는 적합한 바인딩 포인트들을 새로고침 하는 것을 의미합니다.
그 View 컴포넌트는 이 템플릿으로부터 Angular에 의해 구성되어 집니다. 

App/index.html

우리는 ngRepeat 지시어와 두 개의 Angular 표현식을 폰 리스트에 하드 코딩했습니다.

- <li> 태그 안에 ng-repeat=”phone in phones” 속성은 Angular Repeater 지시어입니다.
        Repeater 는 <li> 태그 내에 전체를 탬플릿으로 사용하여, 리스트 안에 각각의 Phone 정보를 <li> 요소로 생성하라고 Angular에게 전달합니다. 

- 중괄호  ({{phone.name}} 과 {{phone.snippet}})안에 래핑되어 있는 표현식은 표현식의 값으로 놓여 질것입니다.

<body> 태그에서 PhoneListCtrl 컨트롤러를 붙인, ng-controller 로 불리 우는 새로운 지시어를 더했습니다.
여기 포인트는 : 

- 중 괄호({{phone.name}} and {{phone.snippet}} 안에 표현식은 우리 어플리케이션 모델에서 언급되어지고 있는,
        우리 PhoneListCtrl 컨트롤러에 셋업되어진 바인딩을 나타냅니다. 

기록 : 우리는 PhonecatApp은 우리 모듈의 이름이다 라는 ng-app=”phonecatApp” 의 사용을 로드하기 위해 Angular 모듈을 명시했습니다.

이 모듈은 PhoneListCtrl 를 포함 할 것입니다. 



Model and Controller

데이터 모델(객체 문자 표기에 폰들의 단순 배열)은 현재 phoneListCtrl 컨트롤러 안에서 예시되어지고 있습니다. 
컨트롤러는 간단히 $scope 파라미터를 가지고 있는 생성자 함수입니다.

App/js/controllers.js 


여기서 PhoneListCtrl 로 불리는 컨트롤러를 선언했고, AngularJS 모듈인, phonecatApp에 컨트롤러를 등록했습니다.
ng-app 지시어(<html> 태그상에)가 지금 Angular 어플리케이션이 부트스트래핑 되어질 때 로드하기 위한 모듈로써
phonecatApp 모듈 이름을 명시하고 있다는 것을 주목하세요. 

비록 컨트롤러는 아직 매우 많이 하고 있지 않지만, 중대한 역할을 하고 있습니다.
우리 데이터 모델에 컨텍스트를 제공함에 따라, 컨트롤러는 우리에게 Model 과 View 사이에 데이터 바인딩을 구축하는 것을 허가 하고 있습니다.
아래 따라서 우리는 프리젠테이션, 데이터, 로직 컴포넌트 사이에 점들을 연결했습니다:

- <body> 태그에 위치되어진 ngController 지시어는 PhoneListCtrl(controller.js 자바스크립트 파일안에 위치한)컨트롤러의 이름을 참조한다.

- PhoneListCtrl 컨트롤러는 컨트롤러 함수안에 주입되어질 $scope 에 Phone 데이터를 첨부한다.

- 이 scope 는 어플리케이션이 정의되어질 때 만들어지는 루트 scope의 원형의 자식입니다.

이 컨트롤러 scope 는 <body ng-controller=”PhoneListCtrl”> 태그와 함께 위치 되어진 모든 바인딩에 이용 가능합니다. 


Scope

Angular 에서 scope의 개념은 매우 중요한 것입니다.

scope 는 함께 작동하도록 템플릿 , 모델, 컨트롤러를 허가하는 접착제로 보여질 수 있습니다.

Angular는 템플릿에 포함된 정보, 데이터 모델 그리고 컨트롤러와 함께, 모델과 뷰들의 분리가 유지되지만, 동기화 되어 scope를 사용합니다.

모델에 만들어 지는 어떤 변화들도 view에 반영되어 집니다 ; view 안에 발생하는 어떤 변화도 모델에 반영되어 집니다.

Angular scope에 대해 좀 더 배우길 원한다면, 문서를 보세요.


Tests 

View로부터 분리된 컨트롤러의 “Angular way”는 개발 되고 있는 코드를 테스트 하는 것을 쉽게 만듭니다.

우리 컨트롤러가 만약 전역 네임스페이스 상에서 사용 가능하다면, 간단히 그 컨트롤러를 Mock Scope 객체와 함께 인스턴스화 할 수 있었습니다.

 

테스트는 PhoneListCtrl 를 인스턴스화 하고 scope가 3개의 레코드를 포함하고 있는 곳에 폰 배열프로퍼티를 검증한다.
이 예제는 Angular에 있는 코드에 대해 유닛 테스트를 얼마나 쉽게 생성하는지 설명합니다.
테스트가 그런 소프트웨어 개발의 치명적인 부분이였던 이래로, 
Angular에서의 테스느는 쉽게 만들수 있어서 개발자들은 테스트를 작성하는 힘을 얻을수 있습니다.


Testing non-Global Controller

연습하면서, 여러분들을 여러분들을 전역 네임스페이스 상에 컨트롤러 함수 가지길 원하지 않을것입니다.

대신, PhonecatApp 모듈에서 익명의 생성자 함수을 통해 그것이 등록되어진 것을 볼수 있습니다.

이번 경우에는 Angular가 이름으로 여러분들의 컨트롤러를 회수할 서비스 ,$controller,를 제공합니다.

여기 $controller를 사용한 같은 테스트가 있습니다.

Test/unit/controllersSpec.js


- 각각의 테스트 전에, Angular에게 phonecatApp 모듈을 로드하라고 전달합니다.

- $controller 서비스를 우리 테스트 함수에 주입하라고 Angular에게 요청합니다.

- PhoneListCtrl의 인스턴스를 생성하기위해 $controller를 사용합니다.

- 인스턴스와 함께, Scope상에 폰 배열 프로퍼티가 3개의 레코드를 포함하는 것에 대한 검증을 진행합니다.


 Writing and Running Tests

작성된 것을 테스트 할 때, Angular 개발자는 Jasmine’s Behavior-driven Development 프레임워크의  체계를 더 좋아합니다. 

비록 Angular는 여러분들에게 Jasmine를 사용하는 것을 요구하지 않지만, 우리는 이 튜토리얼에서 모든 테스트를 Jasmine v1.3 기준으로 작성했습니다.

여러분들은 Jasmine 홈페이지 와 Jasmine 문서를 통해 Jasmin에 관해서 배울수 있습니다.

Angular-seed 프로젝트는 Karam를 사용하여 유닛테스트가 작동되도록 미리 설정되어 있으나, 여러분은 Karma 와 그것에 필수적인 플러그 인이 설치 된 것에 대한 확인이 필요할 것입니다.

여러분은 npm install 을 동작시킴으로써 이걸 설치 할수 있습니다.

테스트를 동작시키고, 그때 변경된 파일들을 보세요.: npm test.

- Karam는 자동으로 크롬브라우저의 새로운 인스턴스를 시작할것입니다. 
        그냥 그걸 무시하고 백그라운드상에서 그것을 동작하게 둔다.
        Karma는 테스트 실행에 이 브라우저를 사용할 것이다. 

- 터미널에서 아래 내용 혹은 비슷한 결과물을 볼수 있을것입니다.

 

예! 테스트가 통과 되었거나 아니거나..

- 테스트를 재가동하기 위해, 그냥 .js 테스트 파일 또는 소스을 변경하세요.

Karma 는 변화를 알아차리고 여러분들을 위해 테스트을 리턴해줄겁니다.

어때요, 달콤하지 않나요?


Karma 열어놓은 브라우저를 최소화 하지 않도록 해주시길 바랍니다.
같은 OS 상에서, 최소화된 브라우저에 할당된 메모리가 제한적입니다. 여러분들의 karma 테스트테 동작하는 것이 극도로 느려지는 결과를 초래합니다.



Experiments


index.html에 다른 바인딩을 추가해 보세요.

<p> Total number of phones : {{phones.length}} </p>

컨트롤러에 새로운 모델 프로퍼티를 생성해보세요 그리고 탬플릿으로부터 그걸 바인딩 해보세요.

$scope.name = “World”;

그리고 새로운 바인딩을 index.html에 추가해보세요.

<p> hello , {{name}}!</p>

브라우저를 새로고침하고 “Hello World!” 라고 말하는지 검증해보세요.

이전 변경을 반영하기 위해 ./test/unit/controllersSpec.js에 컨트롤러에 유닛 테스트를 업데이트 해보세요.

Expect(scope.name).toBe(‘World’);

 

간단한 테이블을 만든 index.html 에 repeater를 생성해보세요.

<table>

<tr><th>row number</th></tr>

<tr ng-repeat=”I in [0,1,2,3,4,5,6,7]”><td>{{i}}</td></tr>

</table>

 

Now , make the list 1-based by incrementing I by one in the binding:

지금부터 1을 시작으로 1씩 증가하는 리스트를 바인딩 안에 만들어 보세요.

<table>

 <tr><th>row number</th></tr>

 <tr ng-repeat=”I in [1,2,3,4,5,6,7]”><td>{{i+1}}</td></tr>

</table>

 

추가 포인트 : 8x8 테이블, 추가적인 ng-repeat를 사용하여 만들어 보세요.

expect(scope.phones.lenght).toBe(3) 를 use toBe(4) 로 만들어 유닛테스트 실패를 만들어 보세요 

 

summary

여러분들은 기능들이 모델,뷰, 컨트롤러 컴포넌트로 분리된 다이나믹 한 어플리케이션을 갖게 되었습니다. 그리고 여러분들은 컴포넌트들을 테스트 하고 있고 , 여러분이 하고 싶은데로 테스트 하고 있습니다.

자 3 단계로 가서, 어플리케이션에 문자 검색을 추가하는 방법을 배워봅시다.