반응형

앵귤라의 기본 구성 요소라합니다.

내용은 뷰와 클래스로 구성됬다네요.

뷰에서 호출된 화면 경로를 제어한다.


각각의 Hook을 implements  하여 Hook 별 처리 내용을 정의 할수 있다.

export class SpyDirective implements OnInit, OnDestroy {

ngOnInit() { this.logIt(`onInit`); } ngOnDestroy() { this.logIt(`onDestroy`); }

}

lifecycle hooks 확인


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

import { Hero } from '../hero';

import { HeroService } from '../hero.service';


@Component({

  selector: 'app-heroes',

  templateUrl: './heroes.component.html',

  styleUrls: ['./heroes.component.css']

})

export class HeroesComponent implements OnInit {

  heroes: Hero[];

  constructor(private heroService: HeroService) { }


  ngOnInit() {

    this.getHeroes();

  }

  getHeroes(): void {

    this.heroService.getHeroes().subscribe(heroes => this.heroes = heroes);

  }

}


Component metadata 

@Component 데코레이터 어노테이션을 붙혀서 선언한다.

selector : CSS 셀렉터 처럼 사용 하면 되고 HTML 에 포함된 요소를 해당 컴포넌트로 랜더링 한다.

templateUrl : 컴포넌트의 주요 뷰를 HTML 템플릿된 파일의 상대경로를 정의한다. 

template : 컴포넌트의 주요 HTML  뷰 코드를 작성한다. 역따옴표를 사용하여 안의 따옵표 코드를 같이 사용 할수 있다.

providers : 사용할 컴포넌트의 의존성 주입하는 프로바이저이다. 배열형태로 정의한다.  컴포넌트의 생성자에서 받아서 인스턴스를 생성한다.

styleUrls : 여기에 정의한 CSS 파일은 해당 컴포넌트에서에 스타일이 적용된다.

style : 해당 컴포넌트에 적용될 스타일 코드를 작성한다.



반응형
반응형


라우팅

우들의 영웅 관광 앱에 새로운 자격요건 이다.


  • 대시보드 뷰를 추가한다.
  • Heroes와 Dashboard사이에 길을 찾을수 있게 추가한다.
  • 사용자들이 뷰에 어느것하나의 영웅 이름을 크릭 할때 , 선택된 영웅의 상세 뷰로 길을 찾는다.
  • 사용자들이 이메일 안에 링크를 클릭 할때, 특별한 영웅의 상세 뷰를 연다.

마쳤을때, 다음처럼 앱이 네비게이트가 가능해질겁니다. 



AppRoutingModule 추가

Angular 모범적인 방법은 분리된 것을 라우터로 환경을 설정 한것을 적재하는 것이고, 최고 레벨 모듈은  root AppModule으로부터 라우링하는것과 임포관례상 모듈 클래스 이름은 AppRoutingModule 이고 app-routing.module.ts는 src/app 폴더 자리에 있다.

CLI를 사용해서 자동생성한다.

ng generate module app-routing --flat --module=app

--flat 자신의 폴더 대신에  src/app 안에  파일을 놓습니다.

--module=app CLI이 register에게 AppModule의 imports 배열에 알려준다.


PS D:\workspace\dev\angular02\angular-tour-of-heroes> ng generate module app-routing -flat --module=app

  create src/app/app-routing.module.ts (194 bytes)

  update src/app/app.module.ts (881 bytes)

자동생성된 파일은 다음과 같다.

src/app/app-routing.module.ts (generated)

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

import { CommonModule } from '@angular/common';


@NgModule({

  imports: [

    CommonModule

  ],

  declarations: []

})

export class AppRoutingModule { }

대게 라우팅 모듈에서 콤포넌트 선언을 못한고 @NgModule.declarations 배열을 삭제 할수 있고 CommonModule 참조도 역시 삭제 할수 있다. .

@angular/router 라이브러리에서 부터 2개 심볼을 import함으로써 RouterModule안에  Routes로 라우터 환경을 설정한다.

RouterModule에 @NgModule.exports 배열을 추가한다. RouterModule을 Exporting 하는 것은  그들이 필요할 AppModule 컴포넌트 에서 지시 가능한 라우터를 만든다. 

AppRoutingModule 다음 과 같다.

src/app/app-routing.module.ts (v1)

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

import { RouterModule, Routes } from '@angular/router';


@NgModule({

  exports: [ RouterModule ]

})

export class AppRoutingModule {}


라우트 추가

라우트는 라우터가 어떤 뷰를 표시하는것을 사용자가 링크를 클릭했을때나 브라우저에 주소창에 URL을 붙혀 넣었을때 알려준다.

보통 앵귤라 라우터는 두개의 속성을 갖는다.

  1. path : 브라우저의 주소바에 매치되는 문자열이다.
  2. component : 라우터가 이 라우터를 찾아갈때 생성 해야하는 콤포넌트다.

URL이  localhost:4200/heroes 과 약간 비슷할때  HeroesComponent를 찾을 예정이다.

라우터에서 참조할수 있는 HeroesComponent를 임포트 한다. 그리고나서 라우터들의 배열을 그 콤포넌트의 한게의 라우터와 함께  정의한다.

import { HeroesComponent }      from './heroes/heroes.component';

const routes: Routes = [

  { path: 'heroes', component: HeroesComponent }

];


셋팅이 완료되었을때, router는 URL 경로 'heroes' 와  표시되는 HeroesComponent를 매치 한다.


RouterModule.forRoot()

첫번째로 라우터를 초기화를 하고 브라우저의 경로 변경 리스닝을 시작 해야만 한다.

RouterModule을 @NgModule.imports 배열에 추가한다. 그리고 임포트한 배열안에서 RouterModule.forRoot()을 부르는 하나의 단계에서 configure을  라우터와 함깨 설정한다.  

imports: [ RouterModule.forRoot(routes) ],

메소드는 forRoot() 라고 불린다. 왜냐면 애플리케이션의 root 레벨에서 그라우터를 설정하는 것이기 때문이다.  forRoot() 메소드는 서비스 프로바이더를  공급하고, 디렉티브는 라우팅을 필요로하고, 현재 부라우저 URL에 기반을둔 항해 초기화를 수행한다.


RouterOutlet 추가


Open the AppComponent template replace the <app-heroes> element with a <router-outlet> element.

AppComponent 템픅릿을 열어  <app-heroes> 요소를 <router-outlet> 요소로 변경한다.

src/app/app.component.html (router-outlet)

<h1>{{title}}</h1>

<router-outlet></router-outlet>

<app-messages></app-messages>

<app-heroes>를 지운다 왜냐하면 HeroesComponent는 사용자가 이것을 찾아가기위해 단지 표시하는것입니다.

<router-outlet>는 라우저가 라우터된 뷰가 어디에 표시되는지 알려준다.

RouterOutlet은 AppComponent가 가능하게된 라우터 디렉티브중의 하나다. AppModule은   RouterModule을 익스포트되는한 AppRoutingModule을 임포트 하기 때문이다.


아래처럼 해보자.

여전히 이 CLI 명령어와 같이  동작  해야한다.

ng serve

브라우저는 앱 제목을 다시 표시하지만 영웅 목록은 아니다.

브라우저의 주소창을 보면 URL마지막에 /가 있다.  HeroesComponent에 라우터 경로는 /heroes 이다.

브라우저 주소창 URL에  /heroes 를 추가한다. 익숙한 영웅들의 주/상세 뷰를  볼수 있다.


링크 네비게이션 추가 (routerLink)

사용자들은  주소창에 URL 라우터를 붙혀넣기를 해야만하는것을 할 필요가없다.  길을 찾기위해서 가능하면  링크를 클릭 해야한다.

<nav> 요소를 추가하고, 그 안에서, anchor 요소 , HeroesComponent에 항해를 유발하는.  수정된 AppComponent 템플릿은 다음과 같다.

src/app/app.component.html (heroes RouterLink)

<h1>{{title}}</h1>

<nav>

  <a routerLink="/heroes">Heroes</a>

</nav>

<router-outlet></router-outlet>

<app-messages></app-messages>


routerLink 속성은 "/heroes"를 설정하며, 그 문자열은 라우터가  라우트에서 HeroesComponent로  매치한다. routerLink는 라우터 네비게이션에서 사용자브라우저가에서  앱 제목과 영웅 목록 링크가  새롭게 다시 보여진다. 그러나 영웅 목록은 아니다.

링크를 클릭한다. 주소창은 /heroes로 갱신 되고 영웅 목록이 보이기 시작한다.

이것을 만들고 링크로 이동하는 기능은 app.component.css에  최종 코드리뷰에 목록 처럼 개인 CSS를 추가하는것 처럼  좋아보인다.


대시보드 뷰 추가

멀티 뷰일때 더 감각적인 라우팅을 만든다. 지금까지 오직 하나의 영웅 뷰 만이었다.

CLI을 이용한 DashboardComponent 추가

ng generate component dashboard

CLI은 DashboardComponent의 파일을 자동생성하고 AppModule에 선언 합니다.

3개의 파일들의 기본 파일의 내용을 다음처럼 교체합니다.


src/app/dashboard/dashboard.component.html

<h3>Top Heroes</h3>

<div class="grid grid-pad">

  <a *ngFor="let hero of heroes" class="col-1-4">

    <div class="module hero">

      <h4>{{hero.name}}</h4>

    </div>

  </a>

</div>


src/app/dashboard/dashboard.component.ts

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

import { Hero } from '../hero';

import { HeroService } from '../hero.service';


@Component({

  selector: 'app-dashboard',

  templateUrl: './dashboard.component.html',

  styleUrls: [ './dashboard.component.css' ]

})

export class DashboardComponent implements OnInit {

  heroes: Hero[] = [];


  constructor(private heroService: HeroService) { }


  ngOnInit() {

    this.getHeroes();

  }


  getHeroes(): void {

    this.heroService.getHeroes()

      .subscribe(heroes => this.heroes = heroes.slice(1, 5));

  }

}

src/app/dashboard/dashboard.component.css

/* DashboardComponent's private CSS styles */
[class*='col-'] {
  float: left;
  padding-right: 20px;
  padding-bottom: 20px;
}
[class*='col-']:last-of-type {
  padding-right: 0;
}
a {
  text-decoration: none;
}
*, *:after, *:before {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}
h3 {
  text-align: center; margin-bottom: 0;
}
h4 {
  position: relative;
}
.grid {
  margin: 0;
}
.col-1-4 {
  width: 25%;
}
.module {
  padding: 20px;
  text-align: center;
  color: #eee;
  max-height: 120px;
  min-width: 120px;
  background-color: #607D8B;
  border-radius: 2px;
}
.module:hover {
  background-color: #EEE;
  cursor: pointer;
  color: #607d8b;
}
.grid-pad {
  padding: 10px 0;
}
.grid-pad > [class*='col-']:last-of-type {
  padding-right: 20px;
}
@media (max-width: 600px) {
  .module {
    font-size: 10px;
    max-height: 75px; }
}
@media (max-width: 1024px) {
  .grid {
    margin: 0;
  }
  .module {
    min-width: 60px;
  }
}


템플릿에 영웅 이름 링크들의 그리드를 통해 주다.

  • *ngFor 반복자는  컴포넌트의 영웅 배열에 많은 링크를   생성합니다.
  • dashboard.component.css에서 부터 링크들은 스타일이 검은색으로 적용된다.
  • 링크들은 아직 어느 곳으로도 가지 않고 곧 갈것이다.

 클래스는 HeroesComponent 클래스와 비슷하다.

  • heroes 배열 속성을 정의한다.
  • 생성자는 앵귤라가 HeroService가 private heroService 속성으로 주입하는것을 기대한다.
  • ngOnInit()의 라이프사이클 hook은 getHeroes을 호출한다.

표시된 영웅들의 번호를 4개로 getHeroes는 줄이다.

getHeroes(): void {

  this.heroService.getHeroes()

    .subscribe(heroes => this.heroes = heroes.slice(1, 5));

}


대시보드 라우트 추가

대시보드로 길을 찾는것은, 라우터가 적절한 라우터를 필요로한다.

AppRoutingModule에서 DashboardComponent를 임포트한다.

src/app/app-routing.module.ts (import DashboardComponent)

import { DashboardComponent }   from './dashboard/dashboard.component';


라우터를 경로가 DashboardComponent로 매치되는것을 AppRoutingModule.routes 배열에 추가한다.

{ path: 'dashboard', component: DashboardComponent },


기본 라우트 추가

앱이 시작될때, 브라우저 주소창은 웹 사이트의 root를 가리킨다. 저것은  어디든 길을 찾지 못한하는 라우터 처럼 어떤 기존 라우트와 매치가 안된다. <router-outlet>의 아래는 비어 있다.

앱이 대시보드를로 자동적으로 찾아가는것을 만드는것은, 다음 라우터를 AppRoutingModule.Routes 배열에  추가한다.

{ path: '', redirectTo: '/dashboard', pathMatch: 'full' },

이 경로는 빈경로와 완전히 일치하는 URL을 경로가 '/dashboard'  경로로 다시보낸다. 

브라우저가 재로고침된 후에, 라우터는 DashboardComponent를  적재한고 브라우저 주소창에 /dashboard URL을 보여준다.


쉘에 대시보드 링크 추가

사용자는 페이지 상단 근처의 탐색 영역에있는 링크를 클릭하여 DashboardComponent와 HeroesComponent간에 앞뒤로 이동할 수 있어야합니다.

AppComponent 쉘 템플릿에 대시보드 네비게이션 링크를 반드시 영웅 링크 위에 추가 한다.


src/app/app.component.html

<h1>{{title}}</h1>

<nav>

  <a routerLink="/dashboard">Dashboard</a>

  <a routerLink="/heroes">Heroes</a>

</nav>

<router-outlet></router-outlet>

<app-messages></app-messages>

브라우저가 재생된후에 링크를 클릭함으로써 두개의 뷰 사이의 길을 자유롭게 찾을수 있다.

반응형
반응형

영웅 수정

애플리케이션은 이제 기본 제목이 있다. 다음으로 영웅정보 표현과 애플리케이션 쉘의 콤포넌트의 배치 할 새로운 콤포넌트를 만든다.


영웅 콤포넌트 만들기

앵귤라 CLI를 이용해서 heroes라는 이름으로 새로운 콤포넌트를  자동생성한다.

ng generate component heroes



ng : 'ng' 용어가 cmdlet, 함수, 스크립트 파일 또는 실행할 수 있는 프로그램 이름으로 인식되지 않습니다. 이름이 정확한지 확인하고 경로가 포함된 경우 경로가 올바른지 검증한 다음 다시 시도하십시오.

위치 줄:1 문자:1

+ ng generate component heroes

+ ~~~

    + CategoryInfo          : ObjectNotFound: (ng:String) [], CommandNotFoundException

    + FullyQualifiedErrorId : CommandNotFoundException


angular/cli 이 설치가 안되었나 해서 angular/cli  설치후 다시실 행 똑 같은 오류 ..

이상하다 싶었다.

ls 명령어 후 다시 컴포넌트 재너레이터 명령 실행하니 5초 정도 걸린후 제너레이터 된 파일이 만들어졌다. 


PS D:\workspace\dev\angular02\angular-tour-of-heroes> ng generate component heroes

  create src/app/heroes/heroes.component.html (25 bytes)

  create src/app/heroes/heroes.component.spec.ts (628 bytes)

  create src/app/heroes/heroes.component.ts (269 bytes)

  create src/app/heroes/heroes.component.css (0 bytes)

  update src/app/app.module.ts (398 bytes)

html과 테스트, ts파일, css 파일이 제너레이터 되어 생성되고, 모듈 파일이 업데이트 되었다.


CLI은 src/app/heroes/ 폴더를 만들고 HeroesComponent의 3개 파일이 자동생성된다.


HeroesComponent 클래스 파일은  다음과 같다.

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


@Component({

  selector: 'app-heroes',

  templateUrl: './heroes.component.html',

  styleUrls: ['./heroes.component.css']

})

export class HeroesComponent implements OnInit {


  constructor() { }


  ngOnInit() {

  }

}

앵귤러 코어 라이브러리를 항상 import 해야된다네요. 그리고 @Component 애노테이션을 함깨 사용한다고 합니다.

@Component는  콤포넌트를 위한 Angular 메터데이터를  명시하는 decorator 이다.

CLI은 3개 메테데이터 속성을 자동생성한다.

  1. selector - 콤포넌트의 CSS 요소 선택자
  2. templateUrl - 콤포넌트의 템플릿 파일이 위치 
  3. styleUrls - 콤포넌트마느이 CSS 스타일 위치


CSS 요소 선택자, 'app-heroes', 이컴포넌트가 부모 컴포넌트의 템플릿에서 확인  html 요소의 이름이 같은것을 매치한다.

컴포넌트 생성 후 바로 싱행된는  ngOnInit는  초기화 로직을 넣기에 좋은 곳이다.

 AppModule 안에 처럼  다른곳에서 가져올수 있도록 항상 컴포넌트 클래스를 내보낸다.  


영웅 속성 추가


영웅이름을 "Windstorm" 으로 HeroesComponent 에 영웅 속성을 추가한다.

heroes.component.ts (hero property)

hero = 'Windstorm';


영웅 보여주기.

heroes.component.html 템플릿 파일을 연다.  Angular CLI 가 자동으로 만든 기본 글을 삭제하고 새로운 영웅 속성 데이터 바인을 변경한다.


heroes.component.html

{{hero}}


HeroesComponent view 보여주기

HeroesComponent를 보여주는것은  shell AppComponent의 템플릿을 추가 해야한다.

app-heroes는 HeroesComponent의 요소 선택자를  기억해라. AppComponent 템플릿 파일에 <app-heroes> 요소를 정확히 title 아래 추가한다, 


src/app/app.component.html

<h1>{{title}}</h1>

<app-heroes></app-heroes>

ng serve 명령을 이용해서 title 과 영웅 이름을 표시를 확인한다.


영웅 클래스 생성

src/app 폴더 안에 자신의 파일을 id와 name 속성을 줘서 영웅 클래스를 생성한다. .


src/app/hero.ts

export class Hero {

  id: number;

  name: string;

}


HeroesComponent 클래스로 돌아와서 Hero 클래스를 가져온다.

컴포넌트의 영웅 프로퍼티 는 Hero 타입으로  리팩터한다. 초기화설정은 1의 id 와  Windstorm 이름으로한다.

수정된 HeroesComponent클래스 파일은 다음 과 같다.

src/app/heroes/heroes.component.ts

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

import { Hero } from '../hero';


@Component({

  selector: 'app-heroes',

  templateUrl: './heroes.component.html',

  styleUrls: ['./heroes.component.css']

})

export class HeroesComponent implements OnInit {

  hero: Hero = {

    id: 1,

    name: 'Windstorm'

  };


  constructor() { }


  ngOnInit() {

  }

}


이페이지는 더이상 적절히 표시되지 않는다. 왜냐면 문자열에서 객체로 변경된 영웅 폼 때문이다.

 [object Object] 로 표시된다.


영웅 객체 표시

템플릿 안에서 상세 레이아웃 안에서 영웅의 이름과 id 그리고 이름을 보여주는것을 알려주는  바인딩 업데이트 한다.

heroes.component.html (HeroesComponent's template)

<h2>{{ hero.name }} Details</h2>

<div><span>id: </span>{{hero.id}}</div>

<div><span>name: </span>{{hero.name}}</div>

브라우저 리프래쉬되고 영웅의 정보를 보여준다.


대문자 파이프 포멧

이처럼 hero.name 바인딩을 수정한다.

<h2>{{ hero.name | uppercase }} Details</h2>

브라우저 리플래시되고 지금 바로 영웅의 이름은 대문자로 표시된다.

대문자를 바인딩을 써넣을때 , 파이프 연산자 | 바로뒤, 내장 UppercasePipe를 동작시킨다

파이프는 문자열 포메팅, 통화 가격, 날짜 와 다른 날짜 표시에 함에 좋은 방법이다.    


반응형

+ Recent posts