PhoneCat Tutorial App 4 - Filtering Repeater

2014. 9. 19. 09:39JS&FRONT/AngularJS

오늘 진행한 부분에 대해서도 크게 어려운 점은 없었지만,
Filter의 효과를 어디에 접목시켜서 잘 쓸것인지 고민해야 겠다. 암튼 시작!


지난 시간에 어플리케이션을 위한 기반을 마련하는데 많은 일들을 했습니다.
그래서 지금부터는 간단한 무언가를 할 것 입니다; 전체 텍스트 검색을 추가할 것입니다.
(예, 간단할 것입니다.)
또한 E2E (End-to-End 를 E2E라고 약자로 사용할겁니다.... 한글로 적당한 말이 생각이 안나요;;) 테스트를 작성할 것입니다. 왜냐하면 좋은 E2E 테스트는 좋은 친구이니까요.
E2E는 여러분들의 어플리케이션에 머물러 있고, E2E에 집중하시고 빠르게 뒤돌아감을 발견하세요. 

- 어플리케이션은 지금부터 검색박스를 갖습니다.

페이지상에 Phone 목록은 사용자가 검색박스에 타이핑하는 것에 따라 변하게 되는 것을 알아 두세요.

Git checkout –f step-3


Controller

컨트롤러에 어떤 변경도 하지 않았습니다.


Template

App/index.html

표준 HTML <input> 태그를 추가하고 Angular의 필터 함수를 ng-repeat 지시어를 위해 입력을 처리하기 위해 사용했습니다.
이건 phone 리스트 상에서 사용자가 검색 표준을 넣게 하고, 즉시 검색의 효과를 볼 수 있게 합니다.
새로운 코드는 아래 내용을 설명 합니다.

- 데이터 바인딩 : 이건 Angular에서 하나의 코어 기능 입니다.

페이지가 로드 될 때,  Angular 입력박스의 이름을 데이터 모델의 같은 이름의 변수에게 바인딩 하고,
두 개 모두 동기를 유지합니다.
이 코드상에서 사용자가 입력박스(query 라는 이름)에 타이핑한 데이터는 즉시 리스트 repeater(phone in phones | filter : query)안에 하나의 필터 입력으로서 이용가능 합니다. 
데이터 모델에 대한 변경사항은 repeater의 입력을 변경하기 위한 원인이 될 때,
repeater는 효과적으로 모델의 현재 상태를 반영하기 위해 DOM을 업데이트 합니다.

- 필터의 사용 : 그 필터함수는 단지 query와 매치되는 것들의 레코드를 포함하는 새로운 배열을
    생성하기 위해 query 값을 사용합니다.

ngRepeat는 filter 필터에 의해 리턴된 phone들의 변경한 개수의 응답으로 view를 자동으로 업데이트 합니다. 
이 과정은 개발자에게는 완전히 쉬운 것입니다.


Test

두번째 단계로, 유닛 테스트를 어떻게 작성하고 동작하는지 배우도록 합니다.
유닛테스트는 JavaScript로 작성된 어플리케이션의 다른 컴포넌트와 컨트롤러를 테스트하기 완벽합니다만
DOM manipulation 또는 우리 어플리케이션에서 작성할 것을 쉽게 테스트 할 수 없습니다.
이런 경우에는 E2E 테스트가 좀 더 나은 선택입니다.
검색기능은 충분히 탬플릿과 데이터 바인딩에 의해 구현되었습니다. 그래서 우린 위 기능이 작동하는 것을
검증하기 위해 E2E 테스트를 작성 할 것 입니다.

test/e2e/scenarios.js


이 테스트는 검색박스 와 repeater 가 정확하게 함께 묶여졌는지를 검증합니다.
얼마나 쉽게 E2E 테스트가 Angular에서 작성되었는지를 알아주세요.
비록 이 예제가 쉬운 것이지만,
이것이 정말 어떠한 함수적이고, 가독성 있는 E2E 테스트를 세팅하기가 쉽다는 점을!


Running End to End Test with Protractor

이 테스트의 구분이 Jasmine으로 작성된 우리의 컨트롤러 유닛 테스트와 매우 많이 같아보여도,
E2E 테스트는 Protractor의 API들을 사용합니다.

Protractor API에 관해서 읽어 보세요 : https://github.com/angular/protractor/blob/master/docs/api.md

유닛 테스트를 위한 테스트 런너인 카르마와 같이 많이,
우리는 Protractor를 E2E 테스트 하기 위해 사용 할 것입니다.
npm run protractor 를 실행 해보세요.
E2E 테스트는 느립니다.
그래서 유닛 테스트와는 다르고, Protractor 는 테스트 작동 후 종료될 것이고, 자동으로 테스트 수행이 모든 파일 변경 시마다 재작동 하지 않을 것입니다.

다시 재동작 시키기 위해서는 npm run protractor를 다시 실행하셔야 합니다.

Note
여러분의 어플리케이션은 protractor를 가지고 테스트 하기 위한 웹 서버를 통해 서비스되어지는 것을 확실히 해야 한다.

npm start 를 통해서 이것을 할수 있습니다.
여러분은 protractor를 인스톨하고, npm run protractor 가 동작하기 이전에 웹 드라이버를 업데이트 해야 하는 것에 확실히 해야 할 필요가 있습니다.
여러분은 npm install 과 npm run update-webdriver를 여러분 터미널 안에서 issuing하는것에 의해 이것을 할 수 있습니다.


Experiments

Display Current Query

index.html 안에 바인딩 한 {{query}}를 추가해서 query 모델의 현재 값을 보여주세요.
그리고 여러분이 입력박스에 타이핑 할 때 그것이 어떻게 변하는지 보세요.

 지금 쿼리는 : {{query}} 입니다. 

Display Query in Title

HTML 페이지 타이틀에 나타내기 위해 query 모델의 현재 값을 우리가 어떻게 가져오는지 보시죠.

- Describe 블록안에 E2E 테스트를 추가하세요. test/e2e/scenario.js 아래와 같이 보여야 합니다.


이 테스트 실패를 보기 위해 Protractor를 작동시키세요.
- 여러분들은 단지 아래와 같이 {{query}}를 title 태그요소를 추가 했었다면, 이라고 생각했었을 것 같다.


<title>Google Phone Gallery: {{query}}</title>


- 그러나, 여러분이 이 페이지를 리로드 해보면, 기대한 결과를 볼수 없을 것이다.

이건 “query”모델은 body 요소상에 ng-controller=”PhoneListCtrl” 지시어에 정의되어진 scope 안에 살고 있기 때문이다.


<body ng-controller=”PhoneListCtrl”>


만약 여러분들이 그 query 모델을 <title> 요소로부터 바인딩 하기를 원한다면, 여러분은 ngController 지시어를 HTML 요소에서 옮겨야 하는데, 그건 Body 와 title 요소의 두 가지 모두의 공통부모 이기 때문입니다.


<html ng-app=”phonecatApp” ng-controller=”PhoneListCtrl”>

Body 요소에서 ng-controller 지시어를 확실하게 지워주세요.

테스트가 지금 통과되는 것을 보기 위해 , npm run protractor 를 재 실행하세요.

이중 중괄호 사용은 title 요소안에서 잘 작동되는 동안, 잠깐동안 페이지에서 로딩할 때 사용자에게 정말 사라지는 것을 느꼈을수도 있습니다.

보다 나은 방법은 페이지 로딩하는 동안 사용자에게 안보이게 하는 ngBind 또는 ngBindTemplate 지시어를 사용하는 것입니다.


  <title ng-bind-template="Google Phone Gallery: {{query}}">Google Phone Gallery</title>


Summary 

전체 문장 검색을 추가하는 것과 검색이 동작하는 것을 검증하는 테스트를 포함함 시켰습니다.

자, 4단계로 가서 phone 어플리케이션에 소팅 능력을 추가하는 방법에 대해서 배워 봅시다.