Kendo UI 를 Angular 2 와 사용하기

                                     http://www.telerik.com/blogs/using-kendo-ui-with-angular-2 번역





올해 8 월, 몇 달 간의 노력 끝에 Kendo UI For Angular 2 Beta.를 발표했으며 그 이후로 우리는 1 월로 예정된 출시 후보에 대한 작업에 매진하였습니다. 우리는 이러한 구성 요소에 매우 흥분하고 있으며, 그 결과를 기다릴만한 가치가 있다고 믿습니다.

새로운 Angular 2 구성 요소를 시작하기 전에는 Kendo UI For jQuery와 완전히 다른 점이 있다는것을 아셔야합니다. 여러분 모두와 마찬가지로, 나는 이 이상한 새로운 개념과 모듈, 지시어 등의 새로운 세계에서 Kendo UI를 사용하는 법을 배워야 합니다. 최근에 베타 구성 요소로 Kendo UI와 Angular 2를 실행하는 것이 어떤 것인지 보기 위해 앉아있었습니다. 이것은 제 경험에 대한 기술입니다.

시작 포인트 잡기 

Angular 2에 대해 더 어려운 점 중 하나는 단지 시작하는 것입니다. 우리가 페이지에 스크립트 태그를 몇개 던저 놓고 끝낼 수있는 시대는 이제 끝났습니다. Angular 2는 많은 의존성을 가지고 있으며 모든 JavaScript를 자체 JavaScript와 함께 제공하고 JavaScript를 브라우저 간 호환 가능하게 만드는 빌드 단계가 필요합니다. 다행히도 많은 훌륭한 도구와 스타터 키트가 있습니다. 유감스럽게도, 그들은 모두 다른 모듈 로더를 사용합니다. 따라서 Kendo UI를 시작하는 방법은 사용하는 모듈 로더에 따라 다릅니다.


SystemJS vs Webpack

자바 스크립트 번들 / 모듈 로더 세계에는 현재 두 개의 주요 경쟁자가 있습니다. Webpack은 React 개발자가 널리 채택하였으며 SystemJS는 CommonJS, RequireJS 또는 ES6과 같은 모든 유형의 JavaScript 모듈을 로드하는 데 실제로 도움이되는 범용 모듈 로더입니다.

Angular 2를 선택하는 시작 키트에 따라 SystemJS 또는 Webpack을 사용하게됩니다. 문제는 이 모듈 로더 중 하나에 익숙하지 않은 경우 어느 모듈이 곧바로 사용되는지 알지 못할 수도 있다는 것입니다. 그것은 Kendo UI의 경우 Webpack이 잘 작동하고 SystemJS가 좀 더 많은 구성을 필요로 하기 때문에 문제가 될 수 도 있죠. 

그렇기 때문에 수많은 초보자 용 키트와 GitHub 프로젝트 템플릿을 검토 한 후 Kendo UI와 함께 Angular CLI를 사용하는 것이 좋습니다.


Angular CLI

Angular CLI는 Angular 2로 시작하고 실행하기위한 공식 도구이며 Angular 2 팀과 함께 커뮤니티의 쩌는 사람들이 구성했습니다. 나는 몇 가지 이유로 이것을 권장합니다 :

1. 가장 깨끗하고 단순한 빈 Angular 2 프로젝트를 생성합니다.
2. Webpack을 사용하며 , 거의 모든 것을 구성하는 멋진 일을 대신해줍니다.
3. Angular 2 프로젝트가 많은 파일을 포함하기 때문에 필요한 확실한 제네레이터를 가지고 있습니다.

Angular CLI를 설치하려면 문서를 방문하여 Node 및 npm의 올바른 버전이 설치되어 있는지 확인하십시오. 그 후는 매우 간단해 집니다. 

> npm install -g angular-cli

Windows 사용자 참고 사항 : Visual Studio에 C ++ 라이브러리가 설치되어 있어야합니다. 이러한 라이브러리가 설치되어 있지 않으면 모든 종류의 새 C ++ 프로젝트를 만들고 Visual Studio에서 다운로드하여 설치 됩니다. 그것들은 꽤 거대합니다... 고멘나사이..

CLI가 설치되면 ng 명령을 사용하여 새로운 Angular 2 프로젝트를 작성할 수 있습니다.

> ng new kendo-ui-first-look --style=scss

이것은 새로운 Angular 2 프로젝트를 생성 한 다음 "npm을 경유한 툴링을 위한 패키지 설치"라고 알려줍니다. 생성 된 프로젝트의 의존성을 모두 설치합니다. 꽤 설치할께 많은 패키지이며  i7 및 16 기가의 RAM을 갖춘 Macbook Pro에서 이 단계를 완료하는 데 드는 시간이 그리 짧지 만은 않습니다...CLI가 더 좋아지고 Yarn 같은 것들이 더 좋게 만들어 주길 바랄뿐..

-style = scss 플래그는 SASS가 지원되는 새로운 Angular 2 프로젝트를 원한다는 것을 지정합니다. SASS는 부트스트랩과 같은 외부 CSS 프레임 워크를 포함하고 덮어 쓰기 쉬운 CSS 전처리기입니다.

프로젝트가 생성되면 이동후 serve 명령을 사용하여 프로젝트를 실행할 수 있습니다.

> ng serve

터미널이나 명령 프롬프트를 살펴보면 Webpack이 그 일을하는 것을 볼 수 있습니다.

its-webpack

이 시점에서 앱이 실행 중이지만 브라우저에서 앱을 어떻게 로드할까요? 터미널에서 조금 위로 스크롤하면 앱이 실행되고있는 포트가 어디에 있는지 알 수 있습니다.

where-is-it-running

그리고 브라우저에 URL을로드하면 ...

kendo-ui-first-look


굿! 앱이 작동합니다. 

프로젝트를 살펴 보겠습니다. 프로젝트를 생성 한 디렉토리의 내부에 src/app 폴더가 있습니다. app.component.ts 파일을 열면 title이라는 속성이 있는 Angular 2 구성 요소가 표시됩니다. 이 title 속성은 {{title}} 구문을 사용하여 app.component.html 파일에 바인딩됩니다. app.component.ts에서 title 값을 변경하면 다시 로드하지 않고도 앱에 표시된 메시지가 변경되므로이 브라우저 창을 항상 실행 상태로 둘 수 있습니다.

이 응용 프로그램에 Kendo UI를 추가하기 전에 Kendo UI가 권장하고 완벽하게 통합되는 프레임워크인 Bootstrap을 CSS 프레임워크로 사용하기 위해 가져옵니다.


Including Bootstrap.

Angular CLI에는 엄청난 SASS 지원 기능이 내장되어 있으며 타사 CSS 프레임 워크를 포함시키는 것이 쉽기 때문에 SASS 버전의 Bootstrap을 포함 할 예정입니다.

> npm install bootstrap-sass --save

이렇게하면 npm의 bootstrap이 node_models 폴더로 복사됩니다. 우리가 필요로 하는 것은 부트스트랩 CSS입니다.  styles.scss 파일에 @importstatement와 함께 이것을 넣을 수 있습니다.

$icon-font-path: "~bootstrap-sass/assets/fonts/bootstrap/";
@import "~bootstrap-sass/assets/stylesheets/bootstrap";

첫 번째 행은 부트스트랩 아이콘 글꼴을 가리키는 변수를 설정합니다. 그 변수는 아래에 임포트 된 Bootstrap SASS 파일에서 사용됩니다. Angular 2 CLI에는 SASS에 대한 모든 빌드 단계가 이미 포함되어 있으므로 이 기능은 "잘 작동합니다".

styles.scss 파일에 SASS를 작성하거나 포함 시키면 이 스타일을 전체 응용 프로그램에서 사용할 수 있습니다. Angular 2에는 스타일 캡슐화라는 기능이 있어 하나 이상의 구성 요소에 제한된 스타일을 지정할 수 있지만 전체 응용 프로그램에는 지정할 수 없습니다. 이것은 강력한 기능이며 저스틴 슈 바르 첸 버거 ( Justin Schwartzenberger)의 짧은 프레젠테이션을 자세히 보시고 장려 해주십시오.

https://www.youtube.com/watch?v=J5Bvy4KhIs0

현재 응용 프로그램을 보면 비슷한 모양이지만 글꼴과 같은 기본 CSS 속성을 정규화하기 때문에 글꼴이 변경되었습니다. 더 좋아 보이는군요!

with-bootstrap

이 시점에서 부트 스트랩 CSS 구성 요소를 사용할 수 있습니다. app.component.html의 내용을 다음과 같이 변경하십시오.


<div class="container">
  <div>
    <h1>{{ title }}</h1>
  </div>
</div>


이제 응용 프로그램에  Kendo UI Button을 추가해 보겠습니다. 물론 Bootstrap 버튼을 사용할 수는 있지만 Kendo UI를 포함하는 방법을 배우기 위해 Kendo UI 버튼을 사용할 것입니다. 그 외에, Kendo UI for Angular 2의 기본 테마들은 꽤 놀랍습니다. 기대하세요~ 

먼저 Kendo UI npm 엔드 포인트를 등록해야합니다. Telerik 사용자 이름과 암호 및 전자 메일 주소로 로그인 하도록 요청할 것입니다. (역주: Kendo UI 는 999달러 입니다. 아이폰이나 안드로이드 앱 UI 는 499달러) 

> npm login --registry=https://registry.npm.telerik.com/ --scope=@progress

일단 로깅하면 Kendo UI 버튼 컴포넌트를 인스톨 할 수 있게 됩니다.

> npm install -S @progress/kendo-angular-buttons

@tj_besendorfer는 "ng serve"를 실행하는 동안 Kendo UI 위젯을 설치하면 사용중인 파일이 제대로 복사되지 않아 문제가 발생할 수 있다고 지적했습니다. "unmet dependencies가 @ progress / kendo-data-query @ ^ 0.2.0 및 tslint@^3.0.0."과 같은 문제가 발생하면 개발 웹 서버 (서비스 제공 업체)와 `npm install`을 실행하고 다시`ng serve '를 실행하십시오.

그러면 Kendo UI Button 구성 요소가 npm_modules 디렉토리의 @progressfolder에 설치됩니다. 이 버튼을 사용하려면 사용하려는 모듈로 가져와야합니다. 이 경우 app.module.ts라는 모듈이 하나만 있으므로 여기에 모듈을 가져옵니다.

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';

import { AppComponent } from './app.component';

// Import the Kendo UI Component
import { ButtonsModule } from '@progress/kendo-angular-buttons';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,

    // import the Kendo UI Component into the module
    ButtonsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

마지막으로 Kendo UI 버튼에 필요한 CSS를 포함시켜야합니다. Kendo UI Default 테마는 별도의 NPM 패키지를 통해 제공됩니다.

> npm install -S @telerik/kendo-theme-default

그런 다음 Bootstrap을 포함하는 것과 같은 방법으로 styles.scss에 포함시킬 수 있습니다.

/* Bootstrap CSS */

$icon-font-path: "~bootstrap-sass/assets/fonts/bootstrap/";
@import "~bootstrap-sass/assets/stylesheets/bootstrap";

/* Kendo UI CSS */

@import "~@telerik/kendo-theme-default/styles/packages/all";

이제이 버튼을 app.component.html에서 사용할 수 있습니다.

<div class="container">
  <div>
    <h1>{{ title }}</h1>
  </div>
  <div>
    <button kendoButton [primary]="true" (click)="buttonClicked()">Don't Click Me!</button>
  </div>
</div>

버튼 클릭 이벤트는 buttonClicked라는 이벤트 핸들러에 바인딩됩니다. 해당 이벤트를 app.component.ts 파일에 추가해야합니다.

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  title = 'app works!';

  // Kendo UI Button click event handler
  buttonClicked() {
    alert("Clickity Clack!")
  }
}

clickit-clack

Kendo UI 대화 상자 인 Kendo UI Dialog를 추가하십시오. 이것은 이전에 Kendo UI 창으로 알려져 있었습니다.

> npm install -S @progress/kendo-angular-dialog

Kendo UI Button과 마찬가지로 app.module.ts 파일에서 Kendo UI Dialog 구성 요소를 가져옵니다.

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';

import { AppComponent } from './app.component';

// Import the Kendo UI Components
import { ButtonsModule } from '@progress/kendo-angular-buttons';
import { DialogModule } from '@progress/kendo-angular-dialog';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,

    // import the Kendo UI Components into the module
    ButtonsModule,
    DialogModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Kendo UI 대화 상자 구성 요소의 마크 업을 버튼 바로 아래의 app.component.html 파일에 추가합니다.

<div class="container">
  <div>
    <h1>{{ title }}</h1>
  </div>
  <div>
    <button kendoButton [primary]="true" (click)="buttonClicked()">Don't Click Me!</button>
  </div>
  <kendo-dialog title="Awesome title">
    I am a super simple Kendo UI Dialog!
  </kendo-dialog>
</div>

지금 앱을 살펴보면 대화 상자 구성 요소가 표시됩니다.

simple-kendo-ui-dialog

버튼이 대화 상자를 열었더라면 좋을 것입니다. 이를 위해서 우리는 대화 상자의 * ngIf 속성을 부울로 설정해야합니다. 이 * ng는 대화상자의 가시성을 제어합니다. 따라서 속성을 false 로 설정하면 대화 상자가 표시되지 않습니다. 토글하면 대화 상자가 나타나고 배경이 어두워집니다.

<div class="container">
  <div>
    <h1>{{ title }}</h1>
  </div>
  <div>
    <button kendoButton [primary]="true" (click)="buttonClicked()">Don't Click Me!</button>
  </div>
  <kendo-dialog title="Awesome title" *ngIf="dialogOpen" (close)="dialogClosed()">
    I am a super simple Kendo UI Dialog!
  </kendo-dialog>
</div>

즉, buttonClicked 이벤트는 단순히 dialogOpen이라는 속성을 true로 설정하면 됩니다. 그러면 kendo 대화상자가 보여지는것(나타나는것)이죠. 그리고 close 이벤트는 false로 다시 토글합니다.

마지막으로  Angular 2 바인딩을 보여주기 위해 title 속성도 변경합니다.

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  title = 'app works!';
  dialogOpen = false;

  // Kendo UI Button click event handler
  buttonClicked() {
    this.dialogOpen = true;
  }

  dialogClosed() {
    this.dialogOpen = false;
    this.title = "Nice Job!";
  }
}

kendo-dialog

You’re Ready To Go!


이를 통해 Kendo UI와 Bootstrap을 갖춘 Angular 2 응용 프로그램을 만들었고 이제는 무엇이든 만들 준비가되었습니다!

Kendo UI For Angular 2 Beta에는 Grid 및 Data Visualization를 비롯한 가장 널리 사용되는 컨트롤이 많이 있습니다. 우리는 1 월에 릴리스 후보가 나올 예정이며, 여러분이 좋아하는 구성 요소가 더 많이 포함될 것입니다. 내년 초에 더 많은 것을 제공 할 예정입니다. 우리는 당신이 지금이 모든 구성 요소를 갖고 싶어한다는 것을 알고 있으며 솔직히 그렇게 할 것입니다! 그러나 우리는 항상 최선을 다하는 것을 믿었습니다. 때로는 우리가 원하는 것보다 더 많은 시간이 걸립니다. 그러나 우리는 기다릴만한 가치가 있다고 믿습니다.

자세한 내용은 Getting Started Guide 와 Beta components and demos를 확인하십시오.

'Angular & React' 카테고리의 다른 글

Future 패턴과 AngularJS  (0) 2015.05.31
AngularJS 2 무엇이 바뀔것인가?  (0) 2015.05.22


Future 패턴같은것은 이미 컨셉이 나온지 수십년이나 흘렀는데 , 요즘 와서 빛을 발하고 있다.
멀티코어가 일반화되면서 멀티쓰레드개발이 점점 강조되고 있으며, 또한 통신(웹개발포함)향 프로그래밍에서는 비동기적인 로직이 더욱 효율적이기 때문이다. 특히나 현재 대세인 자바스크립트는 비동기프로그래밍에 감을 못잡고는 적극적으로 활용하기 불가능하다.  ( 자바스크립트처럼 어렵고 비직관적인 언어가  짱의 지위에 올랐다는게 개인적으로 굉장히 흥미롭게 생각한다.) 먼저 자바로 Future 패턴에 대해서 살펴보고 이어서 AngularJS 의 $q / Promise 에 대해 알아보자.

이번글은 코드로 말해요가 될것이다. 개발자라면 글 보다는 코드만 보여주면 금방 감을 잡지 않은가~:-)


1. 자바를 이용한 Future 패턴 


먼저 Future 패턴의 클래스 다이어그램을 보자.  

( IFood / Future / ReadFood 의 관계는 Proxy 패턴이다. 매우 많은 패턴이 저런 모양을 가지고있다. 컴포지트,데코레이터,프록시, 어댑터, 인터프리터 등등  결국 모양 과 패턴은 전혀 상관이 없다. "의도" 가 중요한것이다.)


당신은 주말에 꿀 같은 휴식을 취하고있다.  복면가왕을 보다보니 출출해서 피짜헛에서 피자를 하나 시켜먹어야겠다고 생각했다.  

1. 주문을 한다.

2. 문앞에서 하염없이 기다린다.


맞나?  

그렇지 않다. 우리는 보통 주문을 한 다음에 보던 TV 를 계속보던가 ,  똥싸러 가거나  다른 일을 하게된다. 

이런걸 비동기적인 행동이라고 한다. 위에 하염없이 기다리는것을 동기적( 블로킹 되었다라고도 ) 이라고 한다.

다시 저 위의 다이어그램을 살펴보자. 


클라이언트 ( 당신 ) 은  레스토랑( 피짜헛) 에 주문을 하고  기다리는 코드는 대략 아래와 같다. 

Restaurant rest = new Restaurant();

Pizza pz = rest->requestPizza();     // 요기서 피자 올때까지 계속 기다림!!

eat(pz); // 피자 오면 냠냠!!!! 

이런식으로 코드가 진행된다면  직관적이라  코드리딩이 쉽고 에러날 확률이 줄어들겠지만  피자만들고 배달오는 시간동안 기다려야하기때문에 굉장히 지루하면서, 시간낭비라 할수있다. 그래서 결국 피자만드는 시간이 빠르면 빠를수록 동기적으로코딩하는게 나을테고, 느리면 느릴수록 비동기적으로 코딩하는게 나을것이다. 


그럼 비동기적으로는 어떻게 될까?  위의 UML 에 나온 클래스들을 기반으로 대략 코드를 보자.

Restaurant rest = new Restaurant();

Future  ticket = rest->requestPizza(); //전화로 주문을 한후에, 티켓을 받는다.(티켓에 어떤 능력이있다고 하자)   

boolean b = future->isComplete();     // 티켓을 통해서 완료됬는지 (배달이 집앞에 왔는지) 알수있다. 

if(b){

eat(future->getPizza());    // 집앞에 배달이 왔으면 냠냠 먹는다. 

}

else{                                      // 배달 안왔으면 하던일을 한다.

      .... TV 를 보거나 똥을 싼다 ....

       .... // 좀 지나서 

while(!future->isComplete()){  // 시간이 지나서 배달 올 때쯤에 다시 확인해본다.   

          Sleep(100);                       // 아직 안왔으면 올때까지 기다린다.   

}

eat(future->getPizza());         // 피자를 냠냠!!! 

}

 이런식으로 Future 객체를 사용하는것이 Future 패턴이다.  보면 알겠지만  무엇인가 일을 시킨후에 바로 리턴받고 자기 할일을 한다. 리턴받은 객체(Future) 를 통해서 간간히 자기가 시킨 일의 결과를 확인할수있게된다. 

조금 코드가 복잡해졌지만, 시간 활용도가 매우 높아졌다. 


기본적인 Future 패턴을 살펴보았는데,  여기에 좀 더 양념을 뿌려볼까 한다. 위에 코드를 보면 isComplete 를 통해서 계속 완료됬는지 안됬는지 신경써야한다는 단점이 있다. 어떻게 해결할까? 

"콜백" 함수를 이용하면 좋을거 같다.  다음 코드를 살펴보자 (pseudo코드) 

Restaurant rest = new Restaurant();

rest->requestPizza( new SuccessHandler() {

                                                                 @Override

                                                                 public void eat(Pizza piz) { 

//피자 냠냠!!

                                                                 }

 });

이런식으로 애초에 콜백함수를 요청함수에 넣어서 놓고 있어버릴수도있다.  근데 이것의 단점은 무엇일까??

내가보기엔 이렇게 하면 어떤 요청을 하고나서 내가 더 세세하게 제어할수있는 기회가 줄어들거 같다. 

자 이쯤되면  위의 Future 클래스들은 어떻게 생겼는지 궁금할것이다. (궁금하지 않으면 곤란하다) 

내부소스를 살펴보도록하자.

public class Restaurant {

public IFood requestPizza(){

final Future future = new Future();

new Thread(){

public void run(){

RealFood real = new ReadFood();

real.makePizza();

real.deliver();

future.setReadData(real);

}.start();

return future;

}

 이해가는가 ??  

1.쓰레드 A 는 Future 객체를 만들어서 바로 리턴해준다.

2.쓰레드 B 가 새로 생겨서 진짜 피자를 만들고, 배달하는 작업을 한다. 

3.쓰레드 B 는 피자를 만들면 Future 객체에 집어넣어준다. 

4.쓰레드 A 를 통해서 Future 객체를 가져간 고객은 기다리다가, 완료를 확인하고 먹는다.


이제 Future 클래스를 살펴보자.

public class Future{

private RealFood real = null;

private boolean ready = false; 

public synchronized void setRealData(ReadFood real){    

if(ready){

return ;

}

this.read = real;

this.ready = true;

notifyAll();

}

public synchronized Pizza getPizza(){

wait();

return real.getPizza();

}

public synchronized boolean isComplete(){

return ready;

}

}

당신이 Future 객체를 받은후에 isComplete 를 통해서 피자가 도착했는지 확인하는것이 저 코드인데 

보다시피 , 실제 피자가 들어갈때가지는 false 를 리턴한다.  실제 피자가 들어가면 notify 를 해주고 true 로 세팅해준다. 여기까지가 Future 패턴의 기본이다.


다시 Restaurant  클래스를 보도록하자.  지금 예제는 단순예제이기때문에 Restaurant 클래스의 requestPizza 안에 저렇게 워커쓰레드가 돌아가지만 좀더 확장하려면  자신만의 큐를 가지고있는 능동형 객체에 할일을 넘겨주는 방법이 깔끔하다. 그러기 위해서 ActiveObject 를 이용하면 될것이다. (http://okky.kr/article/279263 참고) 


2. AngularJS 와 비동기 기법들 

AngularJS 는 프런트엔드 MVC프레임워크로 , 음 저런 딱딱한 용어보다는 Ajax 코딩할때 굉장히 쉽고 편하게 코딩을 도와주는 놈이다. 프런트엔드 코딩을 엄청 단순화 해준다. 더 와닿는가??

예를들어서 Rest 서버로 get 호출을 하는 ajax 코딩을할때, 넘겨받은 데이터를 Display 해줘야하는 과정을 거치는데 양방향 바인딩을 통해서 엄청~~나게 이 작업을 쉽고 직관적으로 해준다.

이제부터 AngularJS 의 promise 를 살펴보도록하자.  위에서 살펴본 Future가 promise 라고 생각하면 된다.(확장됨) AngularJS  의  $http 를 통해서 Ajax 코딩을 할때 비동기적으로 하게되는데, 그 전에 $q 와 promise 를 살펴보자.


$q 서비스 

AngularJS는 Common JS Promises/A 스펙에 대한 구현 API를  $q 서비스를 이용해 제공한다. $q 서비스는 Kris Kowal의 Q.js에 영감을 받아 구현되어 이름이 $q 이다. $q 서비스는 Q.js에 비해 제공하는 기능은 적지만 AngularJS의 scope 모델의 데이터 바인딩에 대한 처리가 최적화돼 있다.


다음 소스를 보자!

var Person = function ( name ) {
this.eat = function (food) {                                      //  주문이 도착했을때 발생할  콜백함수.
 console.info(name + " is eating " + food);
}
};

....

var pizzaOrderSystem = $q.defer();
var pizzaDelivered = pizzaOrderSystem.promise;

pizzaDelivered.then(john.eat);     // 피자가 도착했을때 발생할  콜백함수 등록 

pizzaOrderSystem.resolve("슈퍼슈프림");   // 피자가 도착했다고 알림 


 $q.defer();   =>  &q 서비스는  defer 객체를 가지고있는데, 이 놈이 무엇을 하는지 집중해 보자. 
 
defer 는  크게 2가지를 가지고있는데 , 

첫째.  defer 는 promise 객체를 가지고있다.  위에 언급했듯이 promise 는 future + 알파이다.  

피자가게를 다시 생각해보자.  피자를 시키고 future 를 받은것처럼 여기서는 promise 를 받게된다.

promise 에 콜백을 등록하여 미래에 일어날 일에 대한 구현을 등록해놓는다

promise.then(success, fail);    // 피자주문이 성공했을때 와 실패했을때 각각 콜백함수를 등록한다. 

두번째, defer 는 resolve 와 reject 함수를 가지고있다. 이것은  위의 자바 Future 패턴에서 없던 내용인데 ,  resolve 를 통해서 일 (피자도착) 이 완료됬다는걸 알려준다. 위에서 pizzaOrderSystem.resolve("슈퍼슈프림");  를 보면 슈퍼슈프림 피자가 도착했다고 알려주는것을 볼수있다. 


좀 더 구체적으로 피자 가게에 관한 자바스크립트 코드를 살펴보도록하자.

var Restaurant = function ( $q , $rootScope){

var currentOrder;

this.takeOrder = function (orderedItems) {

currentOrder = {

deferred : $q.defer(),

items.orderedItems 

};

return currentOrder.derred.promise;

};


this.deliverOrder = function(){

currentOrder.deferred.resolve(currentOrder.items);

$rootScope.$digest();

};

};

....

pizzaStore = new Restaurant($q, $rootScope);                        // 피자가게 객체를 생성. 

var pizzaDelivered = pizzaStore.takeOrder('슈퍼스프림');      // 피자를 주문합니다. promise (future) 객체를 받음. 

pizzaDelivered.then(john.eat);                                                 // 피자가 도착했을때 일어날 콜백함수를 등록

pizzaStore.deliverOrder();                                                   // 피자가 도착했다고 강제로 알려줌. 

코드에서 deliverOrder  함수를 보면 내부에서 resolve 를 호출하는것을 볼수있다. 어떤 일(피자도착)이 완료됬다고 알려준다. 완료됬다는 신호와 동시에 promise (pizzaDelivered)  에 등록한 함수가 실행되는데 그게  pizzaDelivered.then(john.eat);  이다.

대략 AngularJS 에 지원하는 Promise 를 살펴보았다. 이제 이걸 가장 많이 사용하는것에 대한 예제를 살펴보도록하자. 어디에 많이 쓰일까? 그렇다.  Ajax 호출을 한후에 기다렸다가 , 성공했다고 알려오면 성공콜백함수를 호출하여 데이터를 바꾸어주고 바뀐 데이터를 토대로 디스플레이가 바뀌는곳에 사용된다. 

아래 서비스 코드를 보자. 

angular.module('demo-app', [])
  .factory('userService', function($http, $log, $q) {
    return {
     getUser: function(userId) {
    
       var deferred = $q.defer();
       $http.get('/api/users/' + userID)
         .success(function(data) { 
            //요청이 성공하면 약속을 지키고 별도 데이터를 전달한다.
            deferred.resolve({
               name: data.name,
               address: data.address});
         }).error(function(msg, code) {
            //요청이 실패하면 약속을 취소하고 메시지를 전달한다.
            deferred.reject(msg);
            $log.error(msg, code);
         });
       //해당 deferred 객체의 약속을 반환한다.
       return deferred.promise;
     }
    }
   });

위에  $http.get('/api/users/' + userID) 와 같이 Ajax 호출을 한후에 성공하면 성공 콜백함수가 호출된다. 아래처럼

 .success(function(data) { 
            deferred.resolve({
               name: data.name,
               address: data.address});
  })

deferred.resolve 를 실행하는것을 볼수있다. resolve 는 무엇을 하는거라고?? 그렇다  성공했다고 promise 객체에 알려주는역할을 한다. 저 위에 코드에는 나와있지 않지만 UserService 를 사용하는곳에서 getUser 를 호출한후에 promise 객체를 받았을텐데 그곳에서 아마 promise 객체에 성공시 콜백함수를 등록했을것이다. 그 콜백함수를 resolve 를 통해서 실행시켜 줄 것이다. 


참고로 저렇게 서비스(팩토리) 를 이용해서 코딩하지 않고 컨트롤러에서 직접 통신로직을 구현한다면 defer 는 필요없다.

controller('userListCtrl',function($scope, $http) {
    var reqPromise = $http.get('sample.json');        // $http.get 을 통해서 promise (future) 를 받음.

    reqPromise.success(function(data) {               // promise 에 성공했을때 실행할 콜백등록 
      $scope.userList = data;
    });

    reqPromise.error(function(data) {
      console.error("Ajax 에러 발생");
    });
});

보다시피 위에는 defer 라든지 resolve 가 사용되지 않았다. 이상 자바언어를 통해서 Future 패턴을 살펴봐서 인사이드를 이해하고  AngularJS 의 promise 와 $http 를 통해 future 패턴을 활용해보았다. 




레퍼런스 

http://en.wikipedia.org/wiki/Futures_and_promises

http://webframeworks.kr/tutorials/angularjs/angularjs_promise_deferred/ 

http://www.yes24.com/24/goods/13527426?scode=032&OzSrank=4

http://www.yes24.com/24/goods/2922297?scode=032&OzSrank=7





'Angular & React' 카테고리의 다른 글

Kendo UI 를 Angular2 와 함께 사용하기  (0) 2017.03.17
AngularJS 2 무엇이 바뀔것인가?  (0) 2015.05.22

http://www.sitepoint.com/whats-new-in-angularjs-2/            원문 

http://witinweb.tumblr.com/post/114402573107/angularjs-2-0  번역되어진 싸이트 

https://www.youtube.com/watch?v=-8P8NO8X-mQ  참고 영상



 

왜 Angular 2.0인가?

Angular 2.0 개발은 다음의 문제를 다루기 시작했습니다:

모바일

새 버전은 모바일 앱 개발에 초점을 맞출 것입니다. 그 근거는 모바일(성능, 로드 시간 등)에 관련된 이슈들이 해결된 이후에 테스크탑 측면이 다뤄지기 더 쉬울거라는 점입니다.

모듈

성능 개선의 결과로 다양한 모듈들이 Angular의 핵심에서 제거될 것입니다. 계속 증가하는 Angular의 모듈 생태계에서 여러분이 원하는 부분을 선택하고 가져올 수 있을 것입니다.

모던 브라우저

Angular 2.0은 ES6와 “늘 싱싱한” 모던 브라우저(이들은 최종버전이 자동으로 업데이트 된다.)들을 타켓으로 삼을 것입니다. 이것은 개발을 더 어렵게 만드는 다양한 핵들과 2차 해결책들을 제거함으로서 개발자들이 자신의 비즈니스 도메인에 관련된 코드에만 집중할 수 있도록 해줍니다.

논란에 대해

ng-conference 동안 버전 2.0으로 마이그레이션하는 방법에 대한 언급은 없었습니다. 그것은 또한 2.0버전으로 그대로 점핑할 경우 이전 버전과 어떠한 호환성도 없을 것이기 때문에 Angular 1.3 어플리케이션들이 깨질 수 있음을 의미합니다. 이 이후에 개발자 커뮤니티에서는 새로운 Angular 1.3 프로젝트를 시작할 가치가 있는지에 대한 몇몇 개발자들의 의문 제기에 대해 불확실성과 추측이 난무해왔습니다.

어떤 변화가 있는가?

AtScript

AtScript는 ES6의 확대집합이며 Angular 2.0을 개발하는데 사용되었습니다. 이것은 ES5 코드를 생성하기 위해 Traceur 컴파일러로 처리되며 컴파일 시간 체크 대신 런타임 형식 (진위형)구문을 생성하는 데 TypeScript의 형식 구문을 사용합니다. 그러나 AtScritp는 필수가 아닙니다—여러분은 여전히 Angular 어플리케이션을 작성하기 위해 AtScrit 대신 일반 자바스크립트/ES5 코드를 사용할 수 있습니다.

향상된 의존성 주입(DI)

의존성 주입(그 자신 자체가 아니라 객체에 의존성을 전달하는 소프트웨어 디자인 패턴입니다)은 Angular의 다른 경쟁자들과 근본적으로 다른 이유중 하나입니다. 이것은 특히 모듈개발과 컴포넌트 분리의 측면에서 유리합니다. 그러나 Angular 1.x에서 이것을 구현하는 데에 문제가 많았습니다. Anuglar 2.0은 이런 문제를 해결할 뿐만 아니라 자식요소 주입, lifetime/scope 제어와 같은 기능들도 추가될겁니다.

주석

AtScript는 함수와 메타데이터를 연결하는 도구를 제공합니다. 이것은 DI 라이브러리(함수를 호출하거나 클래스의 인스턴스를 생성 할 때 DI 라이브러리는 관련 메타 데이터를 확인합니다)에 필요한 정보를 제공함으로써 객체 인스턴스의 구성을 용이하게합니다. Inject 주석을 제공함으로서 파라미터 데이터를 쉽게 오버라이드 할 수 있을 것입니다.

Child Injectors

child injector는 자식레벨에 오버라이딩 할 수 있는 능력을 가지고 부모의 모든 서비스를 상속합니다. 요구에 따라 여러 타입의 객체에서 호출될 수 있고 자동으로 다양한 scope에서 오버라이드 됩니다.

Instance Scope

향상된 DI 라이브러리는 인스턴스 스코프 제어를 특징으로 할 것입니다. 이것은 child injectors와 자기 자신의 scope 지시자를 함께 사용하면 더욱 강력해질 것입니다.

템플릿과 데이터 바인딩

애플리케이션을 개발할 때 함께가는 템플릿화와 데이터 바인딩에 대해서 알아봅시다.

동적 로딩

이것은 Angular의 현재 버전에서 누락된 사항입니다. 이것은 Angular 2.0에서 해결될 것이며 개발자들이 즉각 즉각 새로운 디렉티브들과 컨트롤러들을 추가할 수 있게 할 것입니다.

템플릿

Angular 2.0에서 템플릿 컴파일 과정은 비동기적일 것입니다. 코드 ES6 모듈 사양을 기반으로, 모듈 로더는 단순히 구성 요소 정의들을 참조하여 의존성을 로드할 것입니다.

디렉티브(Directives)

Angular 2.0에서는 세 가지 종류의 디렉티브들이 있을 것입니다.

  • 컴포넌트 디렉티브 - 이것은 자바 스크립트, HTML 또는 선택 사양 인 CSS 스타일 시트에 로직을 캡슐화하여 재사용 가능한 구성 요소를 작성합니다.
  • 장식적 디렉티브 - 이 디렉티브는 (툴팁이나 ng-show/ng-hide를 사용한 토글 요소와 같은) 장식적인 요소들을 사용하게 될 것입니다.
  • 템플릿 디렉티브 - 이것은 HTML을 제사용 가능한 템플릿으로 변환할 것입니다. 템플릿을 인스턴스화하고 그것을 DOM에 주입하는 것이 완전히 디렉티브 작성자에 의해 컨트롤되어질 것입니다. 예를 들면 ng-if 및 ng-repeat가 포함됩니다.

라우팅 솔루션

초기 Angular 라우터는 단지 몇 가지 단순한 케이스를 처리할 수 있도록 설계되었습니다. 그러나 프레임워크가 성장함에 따라 더 많은 기능들이 묶여지게 되었습니다. Angular 2.0에서의 라우터도 역시 단순하게 설계되었지만 확장가능합니다. 이것은 아래의 단순한 기능들이 포함되어있습니다:

  • Simple JSON-based Route Config
  • Optional Convention over Configuration
  • Static, Parameterized and Splat Route Patterns
  • URL Resolver
  • Query String Support
  • Use Push State or Hashchange
  • Navigation Model (For Generating a Navigation UI)
  • Document Title Updates
  • 404 Route Handling
  • Location Service
  • History Manipulation

이제 Angular 2.0을 새로운 차원으로 향상시키는 촉매제인 개선된 라우터의 기능들을 살펴보겠습니다.

자식 라우터(Child Router)

자식 라우터는 자기 자신의 라우터에 함께 제공됨으로서 더 작은 애플리케이션에 그 애플리케이션의 각 컴포넌트를 변환할 것입니다.

스크린 활성자(Screen Activator)

이것은 can* 콜백함수 세트들을 통해 탐색 주기 전반에 거처 더 훌륭한 제어를 개발자들에게 제공할 것입니다:

  • canActivate – Allow/Prevent navigating to the new controller.
  • activate – Respond to successful navigation to the new controller.
  • canDeactivate – Allow/Prevent navigation away from the old controller.
  • deactivate – Respond to successful navigation away from the old controller.

Design

이 모든 로직은 파이프라인 아키텍쳐 통해 구축됩니다. 파이프라인 아키텍쳐는 놀라울 정도로 쉽게 자기 자신의 단계를 파이프라인에 추가하거나 제거할 수 있도록 해줍니다. 더 나아가 이것의 비동기적인 천성은 파이프라인에 있는 동안 사용자 인증을 위해 서버 요청을 하거나 콘트롤러에 데이터를 로드할 수 있도록 합니다.

Logging

Angular 2.0은 diary.js라고 부르는 로깅 서비스를 포함할 것입니다—이것은 여러분의 애플리케이션에서 소요되는 시간을 측정하는 매우 유용한 이 기능입니다(이것으로 여러분의 코드에서 병목현상을 인지 가능하게 됩니다.).

Scope


$scope는 ES6 클래스들에 우호적인 Angular 2.0에서는 제거될 예정입니다.



'Angular & React' 카테고리의 다른 글

Kendo UI 를 Angular2 와 함께 사용하기  (0) 2017.03.17
Future 패턴과 AngularJS  (0) 2015.05.31

+ Recent posts