CHAPTER 5. The templating syntax

Interpolation

๋ณด๊ฐ„๋ฒ•์€ ๊ฐ„๋‹จํ•œ ์ปจ์…‰์„ ์œ„ํ•œ ํ•˜๋‚˜์˜ ํฐ ๋‹จ์–ด์ด๋‹ค.

@Component({
  selector: 'ponyracer-app',
  template: `
   <h1>PonyRacer</h1>
   <h2>{{numberOfUsers}} users</h2>
  `
})
export class PonyRacerAppComponent {
  numberOfUsers: number = 146;
}

Angular๊ฐ€ ํƒœ๊ทธ๋ฅผ ์ฐพ์„ ๋•Œ๋งˆ๋‹ค ํ™œ์„ฑํ™”๋˜๋Š” PonyRacerAppComponent๊ฐ€ ์žˆ๋‹ค. PonyRacerAppComponent๋Š” numberofUsers ๋ผ๋Š” ๋ณ€์ˆ˜๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. ํ…œํ”Œ๋ฆฟ์€ ํƒœ๊ทธ์•ˆ์— ๊ฐ’์„ ๋ณด์—ฌ์ฃผ๋Š” ํ‘œํ˜„์‹์ธ ์ด์ค‘๊ด„ํ˜ธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ณด์—ฌ์ง€๊ณ  ์žˆ๋‹ค.

<ponyracer-app>
  <h1>PonyRacer</h1>
  <h2>146 users</h2>
</ponyracer-app>

๋Š” ํ•ด๋‹น ๊ฐ’์œผ๋กœ ๋Œ€์ฒด๋  ๊ฒƒ์ด๋‹ค. Angular๊ฐ€ ์ด๋ผ๋Š” ํƒœ๊ทธ๋ฅผ ๊ฐ์ง€ํ•  ๊ฒฝ์šฐ์—, Angular๋Š” PonyRacerAppComponent ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ํ•ด๋‹น ์ธ์Šคํ„ด์Šค๋Š” ํ…œํ”Œ๋ฆฟ์˜ ํ‘œํ˜„์‹์— ๋Œ€ํ•œ ๋ฌธ๋งฅ์ด๋‹ค. PonyRacerAppComponent ์ธ์Šคํ„ด์Šค๋Š” numberOfUsers ๋ผ๋Š” ๋ณ€์ˆ˜๋ฅผ 146์œผ๋กœ ์„ค์ •ํ• ๊ฒƒ์ด๊ณ  ์šฐ๋ฆฌ๋Š” ํ™”๋ฉด์— 146 ๊ฐ’์„ ํ™•์ธํ•  ๊ฒƒ์ด๋‹ค.

๊ฐ์ฒด ์•ˆ์—์„œ numberOfUsers๋ผ๋Š” ๊ฐ’์ด ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ํ…œํ”Œ๋ฆฟ์€ ์ž๋™์œผ๋กœ ๋ณ€๊ฒฝ๋˜์–ด ๋ณด์—ฌ์งˆ ๊ฒƒ์ด๋‹ค. ์ด๊ฒƒ์€ '๋ณ€ํ™” ๊ฐ์ง€'๋ผ๊ณ  ๋ถˆ๋ฆฌ์›Œ์ง€๋ฉฐ Angular์˜ ๊ต‰์žฅํ•œ ์žฅ์ ์ค‘์— ํ•˜๋‚˜์ด๋‹ค.

๊ธฐ์–ตํ•  ์ค‘์š”ํ•œ ํ•œ ๊ฐ€์ง€ ์‚ฌ์‹ค์€ ๋งŒ์•ฝ ์šฐ๋ฆฌ๊ฐ€ value๋ฅผ ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ํ‘œํ˜„ํ•˜๋ ค๊ณ  ํ•œ๋‹ค๋ฉด, Angular ๋Š” undefined ๋ณด๋‹ค๋Š” ๋นˆ ๋ฌธ์ž์—ด๋กœ ๋ณด์—ฌ์งˆ ๊ฒƒ์ด๋‹ค. null ์ผ ๊ฒฝ์šฐ์—๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ด๋‹ค.

๊ฐ„๋‹จํ•œ ๋ณ€์ˆ˜ ๋Œ€์‹ ์— ๋ณต์žกํ•œ ๊ฐ์ฒด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž.

@Component({
  selector: 'ponyracer-app',
  template: `
   <h1>PonyRacer</h1>
   <h2>Welcome {{user.name}}</h2>
  `
})
export class PonyRacerAppComponent {
  user: any = { name: 'Cรฉdric' };
}

๋ณด์‹œ๋‹ค์‹œํ”ผ, ์šฐ๋ฆฌ๋Š” ๊ฐ์ฒด์˜ ์†์„ฑ์— ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์ด ์ข€ ๋” ๋ณต์žกํ•œ ํ‘œํ˜„์‹์„ ์‚ฝ์ž… ํ•  ์ˆ˜ ์žˆ๋‹ค.

<ponyracer-app>
  <h1>PonyRacer</h1>
  <h2>Welcome Cรฉdric</h2>
</ponyracer-app>

๋งŒ์•ฝ ์šฐ๋ฆฌ๊ฐ€ ํด๋ž˜์Šค์— ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๋ณ€์ˆ˜๋ฅผ ํ…œํ”Œ๋ฆฟ์•ˆ์— ์ž…๋ ฅํ•œ๋‹ค๋ฉด ์–ด๋– ํ•œ ์ผ์ด ๋ฐœ์ƒํ• ๊ฒƒ์ธ๊ฐ€?

@Component({
  selector: 'ponyracer-app',
  // typo: users is not user!
  template: `
   <h1>PonyRacer</h1>
   <h2>Welcome {{users.name}}</h2>
  `
})
export class PonyRacerAppComponent {
  user: any = { name: 'Cรฉdric' };
}

์•ฑ์„ ๋กœ๋”ฉํ•˜๋ฉด ์šฐ๋ฆฌ๋Š” ์ด๋Ÿฌํ•œ ์—๋Ÿฌ๋ฅผ ํ™•์ธํ•  ๊ฒƒ์ด๋‹ค.

Cannot read property 'name' of undefined in [{{users.name}} in PonyRacerAppComponent]

์ด์ œ๋Š” ํ…œํ”Œ๋ฆฟ์ด ์˜ฌ๋ฐ”๋ฅธ์ง€ ํ™•์‹  ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋” ๋‚˜์•„์กŒ๋‹ค. Angular 1๋ฒ„์ ผ์—์„œ ๊ฐ€์žฅ ์ž์ฃผ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ ์ค‘ ํ•˜๋‚˜๋Š” ์ด๋Ÿฌํ•œ ์œ ํ˜•์˜ ์˜ค๋ฅ˜๋ฅผ ๊ฐ์ง€ํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ํ•ด๊ฒฐํ•˜๋Š”๋ฐ ์˜ค๋žœ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆด ์ˆ˜ ์žˆ์—ˆ๋‹ค.

๋‚ด ์‚ฌ์šฉ์ž ๊ฐ์ฒด๊ฐ€ ์‹ค์ œ๋กœ ์„œ๋ฒ„์—์„œ ๊ฐ€์ ธ์™€์„œ ์„œ๋ฒ„ ํ˜ธ์ถœ์˜ ๊ฒฐ๊ณผ๋กœ ํ‰๊ฐ€๋˜๊ธฐ ์ „์— undefined๋กœ ์ดˆ๊ธฐํ™”๋˜๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ? ํ…œํ”Œ๋ฆฟ์„ ์ปดํŒŒ์ผ ํ•  ๋•Œ ์˜ค๋ฅ˜๋ฅผ ๋ฐฉ์ง€ ํ•  ์ˆ˜์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์„๊นŒ?

๊ทธ๋ ‡๋‹ค. user.name์„ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€์‹  user?.name์„ ์‚ฌ์šฉํ•˜๋ฉด ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

@Component({
  selector: 'ponyracer-app',
  // user is undefined
  // but the ?. will avoid the error
  template: `
   <h1>PonyRacer</h1>
   <h2>Welcome {{user?.name}}</h2>
  `
})
export class PonyRacerAppComponent {
  user: any;
}

๋‹น์‹ ์€ ์ด์ œ ๋”์ด์ƒ ์–ด๋– ํ•œ ์—๋Ÿฌ๋„ ์—†์„๊ฒƒ์ด๋‹ค. "?."๋Š” ๋•Œ๋•Œ๋กœ ์•ˆ์ „ํ•œ ํ‘œํ˜„์ด๋‹ค. ์ด์ œ ๋‹น์‹ ์€ ํ…œํ”Œ๋ฆฟ์„ ์•ˆ์ „ํ•˜๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๊ณ  ์ ์ ˆํ•˜๊ณ  ํ™•์‹คํ•˜๊ฒŒ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์„๊ฒƒ์ด๋‹ค. ์šฐ๋ฆฌ์˜ ์˜ˆ์ œ๋กœ ๋Œ์•„๊ฐ€๋ณด์ž. ์šฐ๋ฆฌ๋Š” ๋ฐ›์€ ๋ฉ”์‹œ์ง€๋ฅผ ํ‘œํ˜„ํ•  ๊ฒƒ์ด๋‹ค. ์•„๋งˆ๋„ ์šฐ๋ฆฌ๋Š” ๋‹ค์Œ ์Šคํ…์—์„œ๋„ ๋‹ค๊ฐ€์˜ค๋Š” pony races๋ฅผ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ์„๊ฒƒ์ด๋‹ค.

๊ทธ๊ฒƒ์€ ์šฐ๋ฆฌ๋กœ ํ•˜์—ฌ๊ธˆ ์šฐ๋ฆฌ์˜ ๋‘ ๋ฒˆ์งธ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ์ด๋Œ ๊ฒƒ์ด๋‹ค. ํ˜„์žฌ๋กœ์„œ๋Š” ๊ฐ„๋‹จํ•˜๊ฒŒ ๋งŒ๊ธ€ ๊ฒƒ์ด๋‹ค.

// in another file, races.component.ts
import { Component } from '@angular/core';
@Component({
  selector: 'ns-races',
  template: `<h2>Races</h2>`
})
class RacesComponent {
}

์ด์ œ์ด ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ PonyRacerAppComponent ํ…œํ”Œ๋ฆฟ์— ํฌํ•จํ•˜๋ ค๊ณ  ํ•œ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋ฌด์—‡์„ ํ•ด์•ผ ํ•˜๋Š”๊ฐ€?

Using other components in our templates

์šฐ๋ฆฌ๋Š” PonyRace ๊ตฌ์„ฑ ์š”์†Œ ์ธ RacesComponent๋ฅผ ํ‘œ์‹œํ•˜๋ ค๋Š” PonyRacerAppComponent๋ผ๋Š” ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

// in ponyracer_app.ts
import { Component } from '@angular/core';
@Component({
  selector: 'ponyracer-app',
  // added the RacesComponent component
  template: `
   <h1>PonyRacer</h1>
   <ns-races></ns-races>
  `
})
export class PonyRacerAppComponent {
}

๋ณด์‹œ๋‹ค์‹œํ”ผ ํ…œํ”Œ๋ฆฟ์— ์ด์ „์— ์„ ์–ธํ•œ ํƒœ๊ทธ์™€ ๋งค์นญํ•˜์—ฌ RacesComponent ๋ฅผ ํ…œํ”Œ๋ฆฟ์— ์ถ”๊ฐ€ํ•˜์˜€๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด๊ฒƒ์€ ๋™์ž‘ํ•˜์ง€ ์•Š์„๊ฒƒ์ด๋‹ค. ๋‹น์‹ ์˜ ๋ธŒ๋ผ์šฐ์ ธ๋Š” races ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ณด์—ฌ์ฃผ์ง€ ๋ชปํ•œ๋‹ค. ์™œ ๊ทธ๋Ÿด๊นŒ? ์ด์œ ๋Š” ๋งค์šฐ ๊ฐ„๋‹จํ•˜๋‹ค.: Angular๋Š” racesComponent๋ฅผ ์•„์ง ์•Œ์ง€ ๋ชปํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๊ณ ์น˜๋Š”๊ฒƒ์€ ๋งค์šฐ ๊ฐ„๋‹จํ•˜๋‹ค. PonyracerAppComponent ๋ฅผ ์ถ”๊ฐ€ํ•˜์˜€๋˜ ๋ฐฉ๋ฒ•์„ ๊ธฐ์–ตํ•˜๋Š”๊ฐ€? ์šฐ๋ฆฌ๋Š” ์ด์ œ ๋‘ ๋ฒˆ์งธ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์žˆ๋‹ค. ์ด๊ฒƒ๋„ ๋ฐ˜๋“œ์‹œ ์„ ์–ธํ•ด ์ฃผ์–ด์•ผ ํ•œ๋‹ค. racesComponent๋Š” root ์ปดํฌ๋„ŒํŠธ๋Š” ์•„๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ, ์ด๊ฒƒ์€ ์„ ์–ธ์„ ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { PonyRacerAppComponent } from './app.component';
// do not forget to import the component
import { RacesComponent } from './races.component';
@NgModule({
  imports: [BrowserModule],
  declarations: [PonyRacerAppComponent, RacesComponent],
  bootstrap: [PonyRacerAppComponent]
})
export class AppModule {
}

ํด๋ž˜์Šค๋ฅผ ์ง์ ‘์ ์œผ๋กœ ์ „๋‹ฌํ•˜๋ฏ€๋กœ ํด๋ž˜์Šค๋ฅผ ๊ฐ€์ ธ์™€์•ผ ํ•œ๋‹ค. ๊ฐ€์ ธ์˜ค๊ธฐ๋ฅผ ํ•˜๊ธฐ์œ„ํ•ด์„œ๋Š” ์†Œ์Šค ํŒŒ์ผ์ธ races.component.ts ์—์„œ RacesComponent ํด๋ž˜์Šค๋ฅผ ๋‚ด๋ณด๋‚ด์•ผ ํ•œ๋‹ค.

// in another file, races.component.ts
import { Component } from '@angular/core';
@Component({
  selector: 'ns-races',
  template: `<h2>Races</h2>`
})
export class RacesComponent {
}

์ด์ œ reces ์ปดํฌ๋„ŒํŠธ๋Š” ์šฐ๋ฆฌ์˜ ๋ธŒ๋ผ์šฐ์ ธ์— ์ด๋ ‡๊ฒŒ ๋ณด์ผ ๊ฒƒ์ด๋‹ค.

<ponyracer-app>
  <h1>PonyRacer</h1>
  <ns-races>
   <h2>Races</h2>
  </ns-races>
</ponyracer-app>

Property binding

๋ณด๊ฐ„๋ฒ•์€ ํ…œํ”Œ๋ฆฟ์—์„œ ๋™์ ์ธ ๋ถ€๋ถ„์„ ๊ฐ–๋Š” ์œ ์ผํ•œ ๋ฐฉ๋ฒ• ์ค‘ ํ•˜๋‚˜์ด๋‹ค. ์‹ค์ œ๋กœ ์šฐ๋ฆฌ๊ฐ€ ๋ณด์•˜๋˜ ๋ณด๊ฐ„๋ฒ•์€ Angular 2 ํ…œํ”Œ๋ฆฟ ์‹œ์Šคํ…œ์˜ ํ•ต์‹ฌ ์ธ ์†์„ฑ ๋ฐ”์ธ๋”ฉ์„ ์‚ฌ์šฉํ•˜๋Š” ์‰ฌ์šด ๋ฐฉ๋ฒ•์ด๋‹ค.

Angular 2์—์„œ๋Š” ๊ฐ ๋Œ€๊ด„ํ˜ธ๋ฅผ ๋Œ€๊ด„ํ˜ธ []๋กœ ๋ฌถ์ธ HTML ์š”์†Œ์˜ ํŠน์ˆ˜ ์†์„ฑ์„ ํ†ตํ•ด ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค. ์ฒ˜์Œ์—๋Š” ์ด์ƒํ•˜๊ฒŒ ๋ณด์ด์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” ์œ ํšจํ•œ HTML ์ด๋‹ค. HTML ์†์„ฑ์€ ๋”ฐ์˜ดํ‘œ, ์–ดํฌ ์ŠคํŠธ๋กœํ”ผ, ์Šฌ๋ž˜์‹œ, ๊ฐ™์Œ, ๊ณต๋ฐฑ๊ณผ ๊ฐ™์€ ๋ช‡ ๊ฐ€์ง€ ๋ฌธ์ž๋ฅผ ์ œ์™ธํ•˜๊ณ  ์›ํ•˜๋Š” ๋ชจ๋“  ๊ฒƒ์œผ๋กœ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋‚˜๋Š” DOM ์†์„ฑ์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•˜๊ณ  ์žˆ์ง€๋งŒ ์–ด์ฉŒ๋ฉด ์ด๊ฒƒ์ด ๋‹น์‹ ์—๊ฒŒ ๋ช…ํ™•ํ•˜์ง€ ์•Š์„ ์ˆ˜๋„ ์žˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ HTML ์†์„ฑ์— ์“ฐ๊ณ  ์žˆ๋‹ค.

<input type="text" value="hello">

์œ„์˜ ์ž…๋ ฅ ํƒœ๊ทธ์—๋Š” ๋‘ ๊ฐ€์ง€ ์†์„ฑ, ์ฆ‰ ์œ ํ˜• ์†์„ฑ๊ณผ ๊ฐ’ ์†์„ฑ์ด ์žˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €๊ฐ€์ด ํƒœ๊ทธ๋ฅผ ํŒŒ์‹ฑํ•˜๋ฉด ์ผ์น˜ํ•˜๋Š” ์†์„ฑ ์œ ํ˜• ๋ฐ ๊ฐ’์ด์žˆ๋Š” ํ•ด๋‹น DOM ๋…ธ๋“œ (HTMLInputElement)๋ฅผ ๋งŒ๋“ ๋‹ค. ๊ฐ ํ‘œ์ค€ HTML ์†์„ฑ์—๋Š” DOM ๋…ธ๋“œ์— ํ•ด๋‹น ์†์„ฑ์ด ์žˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ DOM ๋…ธ๋“œ์—๋Š” ํ•ด๋‹น ํŠน์„ฑ์ด์—†๋Š” ์ถ”๊ฐ€ ์†์„ฑ๋„ ์žˆ๋‹ค. (์˜ˆ : childElementCount, innerHTML ๋˜๋Š” textContent )

์‚ฌ์šฉ์ž ์ด๋ฆ„์„ ํ‘œ์‹œํ•˜๊ธฐ ์œ„ํ•œ ๋ณด๊ฐ„๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

{% raw %}<p>{{user.name}}</p>{% endraw %}

๋‹ค์Œ์€ ๊ฐ„๋‹จํ•œ ๊ตฌ๋ฌธ์ด๋‹ค.

<p [textContent]="user.name"></p>

๋Œ€๊ด„ํ˜ธ ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜๋ฉด DOM ์†์„ฑ textContent๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๋ณด๊ฐ„ ์šฉ์œผ๋กœ ์‚ฌ์šฉ ๋œ ๊ฒƒ์ฒ˜๋Ÿผ ํ˜„์žฌ ๊ตฌ์„ฑ ์š”์†Œ ์ธ์Šคํ„ด์Šค์˜ ์ปจํ…์ŠคํŠธ์—์„œ ํ‰๊ฐ€๋˜๋Š” user.name ๊ฐ’์„ ์ง€์ •ํ•œ๋‹ค. ๊ตฌ๋ฌธ ๋ถ„์„๊ธฐ๋Š” ๋Œ€์†Œ๋ฌธ์ž๋ฅผ ์ธ์ง€ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ •ํ™•ํ•œ ์ด๋ฆ„์„ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค. DOM ์†์„ฑ์€ HTML ์†์„ฑ๋ณด๋‹ค ํฐ ์ด์ ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. ๋งŒ์•ฝ ๋‚ด๊ฐ€ ์ž…๋ ฅ ์˜ˆ์ œ์—์„œ value ์†์„ฑ์€ ํ•ญ์ƒ 'hello'๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ๋ฐ˜๋ฉด์— DOM ์˜ Value ์†์„ฑ ๋…ธ๋“œ๋Š” ๋ธŒ๋ผ์šฐ์ €์— ์˜ํ•ด ๋™์ ์œผ๋กœ ์ˆ˜์ •๋˜๋ฏ€๋กœ ์‚ฌ์šฉ์ž๊ฐ€ ํ…์ŠคํŠธ ํ•„๋“œ์— ์ž…๋ ฅ ํ•œ ๋‚ด์šฉ์ด ๋ชจ๋‘ ํฌํ•ฉ๋œ๋‹ค.

๋งˆ์ง€๋ง‰์œผ๋กœ ์†์„ฑ์€ ๋ถ€์šธ ๊ฐ’์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์ง€๋งŒ ์ผ๋ถ€ ์†์„ฑ์€ ์‹œ์ž‘ ํƒœ๊ทธ์— ์กด์žฌํ•˜๊ฑฐ๋‚˜ ๋ถ€์žฌํ•จ์œผ๋กœ์จ ์†์„ฑ์„ ๋ฐ˜์˜ ํ•  ์ˆ˜ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, option ํƒœ๊ทธ์— selected ์†์„ฑ์ด ์žˆ๋‹ค. ์–ด๋–ค ๊ฐ’์„ ์ง€์ •ํ–ˆ๋Š”์ง€์— ์ƒ๊ด€์—†์ด ์˜ต์…˜์ด์žˆ๋Š” ํ•œ ์˜ต์…˜์„ ์„ ํƒํ•œ๋‹ค.

<option selected>Rainbow Dash</option>
<option selected="false">Rainbow Dash</option> <!-- still selected -->

Angular 2 ์™€ ๊ฐ™์€ ์†์„ฑ ์ ‘๊ทผ์„ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด

<option [selected]="isPonySelected" value="Rainbow Dash">Rainbow Dash</option>

pony๋Š” isPonySelected๊ฐ€ true์ด๋ฉด ์„ ํƒ๋˜์–ด ์งˆ ๊ฒƒ์ด๊ณ  ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์„ ํƒ๋˜์ง€ ์•Š์„ ๊ฒƒ์ด๋‹ค. ๊ทธ๋ฆฌ๊ณ  isPonySelected์˜ ๊ฐ’์ด ๋ณ€ํ•  ๋•Œ๋งˆ๋‹ค ์„ ํƒ๋œ ์†์„ฑ๋„ ๋ณ€๊ฒฝ๋  ๊ฒƒ์ด๋‹ค.

Angular 1์—์„œ๋Š” ๋ฒˆ๊ฑฐ๋กญ์ง€๋งŒ ๋งŽ์€ ๊ฒƒ๋“ค์„ ํ• ์ˆ˜ ์žˆ์—ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ด๋ฏธ์ง€๋ฅผ ๋™์  ์ฃผ์†Œ๋กœ ๋ฐ”์ธ๋”ฉ ํ•˜๋Š”๊ฒƒ์ด ์žˆ๋‹ค.

{% raw %}<img src="{{pony.avatar.url}}">{% endraw %}

์ด ๊ตฌ๋ฌธ์€ ํฐ ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ ธ๋Š” src ์†์„ฑ์„ ์ฝ์ž๋งˆ์ž ์ด๋ฏธ์ง€๋ฅผ ๊ฐ€์ ธ์˜ค๋ ค๊ณ  ์‹œ๋„ํ•  ๊ฒƒ์ด๊ณ  ์‹คํŒจ๋กœ ๋ณด์—ฌ์งˆ ๊ฒƒ์ด๋‹ค. ์™œ๋ƒํ•˜๋ฉด ์€ ์œ ํšจํ•œ URL์ด ์•„๋‹Œ HTTP ์š”์ฒญ์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๊ทธ๋ž˜์„œ Angular 1์—์„œ๋Š” ํŠน๋ณ„ํ•œ ๋””๋ ‰ํ‹ฐ๋ธŒ๊ฐ€ ์žˆ์—ˆ๋‹ค. : ng-src

{% raw %}<img ng-src="{{pony.avatar.url}}">{% endraw %}

src ๋Œ€์‹  ng-src๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฌธ์ œ๋Š” ํ•ด๊ฒฐํ•˜์˜€๋‹ค. AngularJS๊ฐ€ ์•ฑ์„ ์ปดํŒŒ์ผํ•˜๊ณ  ๋‚˜๋ฉด src ์†์„ฑ์— ์˜ฌ๋ฐ”๋ฅธ URL์ด ์ถ”๊ฐ€๋˜์–ด ์ด๋ฏธ์ง€ ๋‹ค์šด๋กœ๋“œ๊ฐ€ ์‹œ์ž‘๋œ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด๋Š” ๋‘ ๊ฐ€์ง€ ๋ฌธ์ œ์ ์ด ์žˆ๋‹ค.

  • ๋จผ์ € ๊ฐœ๋ฐœ์ž๋กœ์„œ ng-src์— ์ œ๊ณต ํ•  ๊ฐ€์น˜๋ฅผ ์•Œ์•„์•ผ ํ•œ๋‹ค. ๊ทธ๊ฒƒ์€ 'https://gravatar.com'์ด์—ˆ์Šต๋‹ˆ๊นŒ? ''https://gravatar.com ''? 'pony.avatar.url'? ''? ๋ฌธ์„œ๋ฅผ ์ฝ๋Š” ๊ฒƒ ์™ธ์—๋Š” ์•Œ ๊ธธ์ด ์—†๋‹ค.

  • Angular ํŒ€์€ ๊ฐ ํ‘œ์ค€ ์†์„ฑ์— ๋Œ€ํ•œ ์ง€์นจ์„ ์ž‘์„ฑํ•ด์•ผํ–ˆ์Šต๋‹ˆ๋‹ค.

    ๊ทธ๋“ค์€ ๊ทธ๋ ‡๊ฒŒํ–ˆ๊ณ , ์šฐ๋ฆฌ๋Š” ๊ทธ๊ฒƒ๋“ค์„ ๋ฐฐ์›Œ์•ผํ–ˆ๋‹ค.

    ๊ทธ๋Ÿฌ๋‚˜ ์ด์ œ๋Š” HTML์— ์™ธ๋ถ€ ์›น ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ํฌํ•จ๋  ์ˆ˜์žˆ๋Š” ์„ธ์ƒ์— ์žˆ๋‹ค.

<ns-pony name="Rainbow Dash"></ns-pony>

Web Component๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋Š” ๊ฒฝ์šฐ Web Component ๊ฐœ๋ฐœ์ž๊ฐ€ ์ฃผ์˜ ๊นŠ๊ฒŒ ์ฒ˜๋ฆฌ ํ•œ ๊ฒฝ์šฐ๋ฅผ ์ œ์™ธํ•˜๊ณ  ๋Œ€๋ถ€๋ถ„์˜ JS ํ”„๋ ˆ์ž„ ์›Œํฌ์—์„œ ๋™์  ๊ฐ’์„ ์ „๋‹ฌํ•˜๋Š” ์‰ฌ์šด ๋ฐฉ๋ฒ•์ด ์—†๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ Web Component ์ฑ•ํ„ฐ๋ฅผ ์ฝ์–ด๋ณด๋„๋ก ํ•ด๋ผ.

Web Component๋Š” ๋ธŒ๋ผ์šฐ์ ธ ์—˜๋ฆฌ๋จผํŠธ์ฒ˜๋Ÿผ ๋™์ž‘ํ•ด์•ผ ํ•œ๋‹ค. Web Component๋“ค์€ Angular 2๊ธฐ๋ฐ˜์˜ ์†์„ฑ, ์ด๋ฒคํŠธ, ํ•จ์ˆ˜ ๋“ฑ์„ ๊ฐ€์ ธ์•ผ ํ•œ๋‹ค.

<ns-pony [name]="pony.name"></ns-pony>

๊ทธ๋ฆฌ๊ณ  ์ •์ƒ์ ์œผ๋กœ ๋™์ž‘ํ•œ๋‹ค. Angular๋Š” ์†์„ฑ๊ณผ ์š”์†Œ์— ๋Œ€ํ•œ ๋™๊ธฐํ™”๋ฅผ ์œ ์ง€ํ• ๊ฒƒ์ด๋‹ค. ๋” ์ด์ƒ ์ง€์‹œ์–ด๋ฅผ ๋ฐฐ์šธ ํ•„์š”๊ฐ€ ์—†๋‹ค. ์š”์†Œ๋ฅผ ์ˆจ๊ธฐ๋ ค๋ฉด ํ‘œ์ค€ ์ˆจ๊น€ ์†์„ฑ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

<div [hidden]="isHidden">Hidden or not</div>

ishidden์ด true์ผ ๊ฒฝ์šฐ div๋Š” ์‚ฌ๋ผ์งˆ ๊ฒƒ์ด๋‹ค. Angular๋Š” ์ˆจ๊ฒจ์ง„ ์†์„ฑ๊ณผ ์ง์ ‘ ์ž‘๋™ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋” ์ด์ƒ Angular์—์„œ ์‚ฌ์šฉ๋œ directives ์ค‘์˜ ํ•˜๋‚˜ ์ธ ng-hide์™€ ๊ฐ™์€ directive๋ฅผ ์‚ฌ์šฉํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค. ์Šคํƒ€์ผ ์†์„ฑ์˜ color ์†์„ฑ๊ณผ ๊ฐ™์ด ์ค‘์ฒฉ๋œ ์†์„ฑ์— ์ ‘๊ทผํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

<p [style.color]="foreground">Friendship is Magic</p>

foreground์˜ ์†์„ฑ์ด '๋…น์ƒ‰'์œผ๋กœ ๋ณ€ํ•œ๋‹ค๊ณ  ํ•˜๋ฉด, color๋„ ๋…น์ƒ‰์œผ๋กœ ๋ณ€ํ•  ๊ฒƒ์ด๋‹ค. ๋”ฐ๋ผ์„œ Angular 2๋Š” ์†์„ฑ์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค. ์–ด๋–ค ๊ฐ’์„ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์„๊นŒ? ์šฐ๋ฆฌ๋Š” ์ด๋ฏธ ๋ณด๊ฐ„ ์†์„ฑ property="" ์„ ์ด๋ฏธ ๋ณด์•˜๋‹ค.

{% raw %}<ns-pony name="{{pony.name}}"></ns-pony> {% endraw %}

์ด๊ฒƒ์€ [property] ="expression"๊ณผ ๋™์ผํ•˜๋‹ค.

<ns-pony [name]="pony.name"></ns-pony>

'Pony' ๊ธ€์ž ๋’ค์— pony์˜ ์ด๋ฆ„์„ ๋ง ๋ถ™์ด๊ธฐ๋ฅผ ์›ํ•œ๋‹ค๋ฉด ๋‹น์‹ ์€ ๋‘ ๊ฐ€์ง€ ์˜ต์…˜์ด ์žˆ๋‹ค.

{% raw %}<ns-pony name="Pony {{pony.name}}"></ns-pony>{% endraw %}
<ns-pony [name]="'Pony ' + pony.name"></ns-pony>

๋งŒ์•ฝ ๋‹น์‹ ์ด ๋™์ ์ธ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด property = "value" ์™€ ๊ฐ™์ด ๊ฐ„๋‹จํ•˜๊ฒŒ ์ ์„ ์ˆ˜ ์žˆ๋‹ค.

<ns-pony name="Rainbow Dash"></ns-pony>

์ด๋“ค ๋ชจ๋‘๋Š” ๋™๋“ฑํ•˜๊ณ  ๊ตฌ๋ฌธ์€ ๊ฐœ๋ฐœ์ž๊ฐ€ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์„ค๊ณ„ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋‹ฌ๋ ค ์žˆ์ง€ ์•Š๋Š”๋‹ค. ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ๊ฐ’ ๋˜๋Š” ์ฐธ์กฐ ์˜ˆ๋ฅผ ๊ธฐ๋Œ€ํ•˜๊ณ  ์žˆ๋Š”์ง€๋ฅผ ์•Œ์•„์•ผํ•˜๋Š” AngularJS 1.x์˜ ๊ฒฝ์šฐ์™€ ๊ฐ™๋‹ค๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค.

{% raw %}<ns-pony name="{{pony.fullName()}}"></ns-pony>
<ns-pony [name]="pony.fullName()"></ns-pony>{% endraw %}

Events

์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ฐœ๋ฐœํ•œ๋‹ค๋ฉด, ์ผ์„ ํ‘œ์‹œํ•˜๋Š” ๊ฒƒ์ด ์ผ์˜ ํ•œ ๋ถ€๋ถ„ ์ผ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์‚ฌ์šฉ์ž ์ƒํ˜ธ ์ž‘์šฉ์„ ์ฒ˜๋ฆฌํ•ด์•ผํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์–ด์•ผ ํ•œ๋‹ค. ์ด๋ฅผ ํ—ˆ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๋ธŒ๋ผ์šฐ์ ธ๋Š” ๋‹น์‹ ์ด ๋ฐ›์„ ์ˆ˜ ์ œ์–ด ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ด๋ฒคํŠธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค. click, keyup, mousemove ๋“ฑ ... AngularJS 1.x๋Š” ์ด๋ฒคํŠธ ๋‹น ํ•˜๋‚˜์˜ ์ง€์‹œ๋ฌธ์„ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ , ng-click, ng-keyup, ng-mousemove ๋“ฑ ... Angular 2์—์„œ ์ด๊ฒƒ์„ ๋”์šฑ ๊ธฐ์–ตํ•˜๊ธฐ ์‰ฝ๊ณ  ๊ฐ„๋‹จํ•˜๊ฒŒ ์„ค๊ณ„ํ•˜์˜€๋‹ค.

์šฐ๋ฆฌ RacesComponent๋กœ ๋Œ์•„๊ฐ€์„œ, ์ด์ œ ํด๋ฆญํ–ˆ์„ ๋•Œ ๋ ˆ์ด์Šค๋ฅผ ํ‘œ์‹œ ํ•  ๋ฒ„ํŠผ์ด ํ•„์š”ํ•˜๋‹ค. ์ƒํ˜ธ์ž‘์šฉ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•  ๊ฒƒ์ด๋‹ค.

<button (click)="onButtonClick()">Click me!</button>

์œ„ ์˜ˆ์˜ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด onButtonClick () ๋ฉ”์†Œ๋“œ์˜ ํ˜ธ์ถœ์ด ํŠธ๋ฆฌ๊ฑฐ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

@Component({
  selector: 'ns-races',
  template: `
   <h2>Races</h2>
   <button (click)="refreshRaces()">Refresh the races list</button>
   <p>{{races.length}} races</p>
  `
})
export class RacesComponent {
  races: any = [];
  refreshRaces() {
   this.races = [{ name: 'London' }, { name: 'Lyon' }];
  }
}

๋งŒ์•ฝ ๋‹น์‹ ์˜ ๋ธŒ๋ผ์šฐ์ ธ์—์„œ ์‹œ๋„ํ•˜๋ ค๋ฉด, ๋‹น์‹ ์€ ์ฒ˜์Œ์— ์ด๋Ÿฌํ•œ ๊ตฌ์กฐ๋ฅผ ํ™•์ธํ•  ๊ฒƒ์ด๋‹ค.

<ponyracer-app>
  <h1>PonyRacer</h1>
  <ns-races>
   <h2>Races</h2>
   <button (click)="refreshRaces()">Refresh the races list</button>
   <p>0 races</p>
  </ns-races>
</ponyracer-app>

ํด๋ฆญํ•œ ์ดํ›„์— '0 races'๋Š” '2 races'๋กœ ๋ณ€ํ•  ๊ฒƒ์ด๋‹ค. ๋ช…๋ น๋ฌธ์€ ํ•จ์ˆ˜ ํ˜ธ์ถœ์ด ๋  ์ˆ˜๋„ ์žˆ์ง€๋งŒ ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ ๋ช…๋ น๋ฌธ ๋˜๋Š” ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ ๋ช…๋ น๋ฌธ์˜ ์—ฐ์†์ผ ์ˆ˜๋„ ์žˆ๋‹ค.

<button (click)="firstName = 'Cรฉdric'; lastName = 'Exbrayat'">
  Click to change name to Cรฉdric Exbrayat
</button>

๊ทธ๋Ÿฌ๋‚˜ ๋‚˜๋Š” ์ด๊ฒƒ์„ ๊ถŒ๊ณ ํ•˜์ง€๋Š” ์•Š๋Š”๋‹ค. ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋™์ž‘์„ ์บก์Šํ™” ํ•˜๋Š”๋ฐ ๋” ์ข‹์€ ๋ฐฉ๋ฒ•์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ฝ”๋“œ๋ฅผ ์œ ์ง€ ๊ด€๋ฆฌํ•˜๊ณ  ํ…Œ์ŠคํŠธํ•˜๊ธฐ๊ฐ€ ์‰ฌ์šฐ๋ฉฐ ๋ณด๊ธฐ๊ฐ€ ๋” ๋‹จ์ˆœํ•˜๋‹ค.

์ข‹์€ ์ ์€ ํ‘œ์ค€ DOM ์ด๋ฒคํŠธ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋ฐœ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋Š” ์‚ฌ์šฉ์ž ์ •์˜ ์ด๋ฒคํŠธ์—์„œ๋„ ์ž‘๋™ํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. Angular ๊ตฌ์„ฑ ์š”์†Œ ๋˜๋Š” ์›น ๊ตฌ์„ฑ ์š”์†Œ์—์„œ ๊ฐ€์ ธ์˜ฌ๊ฒƒ์ด๋‹ค. ๋‚˜์ค‘์— ๋งž์ถค ์ด๋ฒคํŠธ๋ฅผ ์‹œ์ž‘ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ดํŽด ๋ณด๊ฒ ๋‹ค.

์ž ์‹œ ๋™์•ˆ RacesComponent ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์ƒˆ๋กœ์šด ๊ฒฝ์ฃผ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ์„ ์•ฑ์— ์•Œ๋ฆฌ๊ธฐ ์œ„ํ•ด ๋งž์ถค ์ด๋ฒคํŠธ๋ฅผ ๋‚ด ๋ณด๋ƒˆ๋‹ค๊ณ  ๊ฐ€์ • ํ•ด ๋ณด์ž.

@Component({
  selector: 'ponyracer-app',
  template: `
   <h1>PonyRacer</h1>
   <ns-races (newRaceAvailable)="onNewRace()"></ns-races>
  `
})
export class PonyRacerAppComponent {
  onNewRace() {
   // add a flashy message for the user.
  }
}

๊ตฌ์„ฑ ์š”์†Œ์— newRaceAvailable์ด๋ผ๋Š” ์‚ฌ์šฉ์ž ์ง€์ • ์ด๋ฒคํŠธ๊ฐ€ ์žˆ๊ณ ์ด ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด PonyRacerAppComponentis์˜ onNewRace () ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜์—ˆ์Œ์„ ์‰ฝ๊ฒŒ ์•Œ ์ˆ˜ ์žˆ๋‹ค. Angular๋Š” ์š”์†Œ์™€ ํ•ด๋‹น ์š”์†Œ์˜ ์ด๋ฒคํŠธ๋ฅผ ์ˆ˜์‹ ํ•˜๋ฏ€๋กœ ๊ฑฐํ’ˆ์ด ๋ฐœ์ƒํ•˜๋Š” ์ด๋ฒคํŠธ์— ๋ฐ˜์‘ํ•œ๋‹ค. ํ…œํ”Œ๋ฆฟ์„ ๊ณ ๋ คํ•ด๋ณด๋„๋ก ํ•˜์ž.

<div (click)="onButtonClick()">
  <button>Click me!</button>
</div>

์‚ฌ์šฉ์ž๊ฐ€ div ์•ˆ์— ํฌํ•จ ๋œ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋”๋ผ๋„ onButtonClick () ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ์ด๋ฒคํŠธ๊ฐ€ ๊ฑฐํ’ˆ์„ ๋‚ด๋ฟœ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋‹น์‹ ์€๋ผ๋Š” ๋ฉ”์„œ๋“œ์—์„œ ์ด๋ฒคํŠธ์— ์•ก์„ธ์Šค ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋‹จ์ง€ $ event๋ฅผ ๋‹น์‹ ์˜ ๋ฉ”์†Œ๋“œ์— ๋„˜๊ฒจ ์ฃผ๋ฉด๋œ๋‹ค.

<div (click)="onButtonClick($event)">
  <button>Click me!</button>
</div>

๊ทธ๋Ÿฐ ๋‹ค์Œ ๊ตฌ์„ฑ ์š”์†Œ ํด๋ž˜์Šค์—์„œ ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌ ํ•  ์ˆ˜ ์žˆ๋‹ค.

onButtonClick(event) {
  console.log(event);
}

๊ธฐ๋ณธ์ ์œผ๋กœ ์ด๋ฒคํŠธ๋Š” ์ง€์†์ ์œผ๋กœ ๊ฑฐํ’ˆ์„ ๋‚ด๋ฉฐ ๊ฒฐ๊ตญ ๊ณ„์ธต์—์„œ ๋‹ค๋ฅธ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ๋ฅผ ํŠธ๋ฆฌ๊ฑฐํ•˜๊ฒŒ๋œ๋‹ค. ์ด ์ด๋ฒคํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ธฐ๋ณธ ๋™์ž‘์„ ๋ฐฉ์ง€ํ•˜๊ณ  ์›ํ•˜๋Š” ๊ฒฝ์šฐ ์ „ํŒŒ๋ฅผ ์ทจ์†Œ ํ•  ์ˆ˜ ์žˆ๋‹ค.

onButtonClick(event) {
  event.preventDefault();
  event.stopPropagation();
}

๋˜ ํ•˜๋‚˜์˜ ํŠน์ง•์€ ํ‚ค๋ณด๋“œ ์ด๋ฒคํŠธ๋ฅผ ๋ณด๋‹ค ์‰ฝ๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

<textarea (keydown.space)="onSpacePress()">Press space!</textarea>

spacekey๋ฅผ ๋ˆ„๋ฅผ ๋•Œ๋งˆ๋‹ค onSpacePress () ๋ฉ”์†Œ๋“œ๊ฐ€ ํ˜ธ์ถœ์žˆ๊ณ  (keydown.alt.space) ๋“ฑ์˜ ์ปค์Šคํ„ฐ๋งˆ์ด์ง•๋œ ์ฝค๋ณด๋ฅผ ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด ๋ถ€๋ถ„์„ ๊ฒฐ๋ก  ์ง“๊ธฐ ์œ„ํ•ด ๋‚˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํฐ ์ฐจ์ด๊ฐ€ ์žˆ์Œ์„ ์ง€์ ํ•˜๊ณ ์ž ํ•œ๋‹ค.

<component [property]="doSomething()"></component>
<component (event)="doSomething()"></component>

์ฒซ ๋ฒˆ์งธ ์†์„ฑ ๋ฐ”์ธ๋”ฉ์€ doSomething () ๊ฐ’์€ ์‹์ด๋ผ๊ณ  ๊ฐ ๋ณ€๊ฒฝ ๊ฒ€์ƒ‰์ฃผ๊ธฐ์—์„œ ํ‰๊ฐ€ ๋œ ์†์„ฑ์„ ์—…๋ฐ์ดํŠธ ํ•  ํ•„์š”๊ฐ€ ์žˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•œ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ๋‘ ๋ฒˆ์งธ์˜ ๊ฒฝ์šฐ๋Š” ์ด๋ฒคํŠธ ๋ฐ”์ธ๋”ฉ์€ doSomething () ๊ฐ’์€ ๋ฌธ์žฅ์ด๋ผ๊ณ  ์ด๋ฒคํŠธ๊ฐ€ ํŠธ๋ฆฌ๊ฑฐ ๋œ ๊ฒฝ์šฐ์—๋งŒ ํ‰๊ฐ€๋œ๋‹ค.

์ •์˜์— ๋”ฐ๋ฅด๋ฉด ๊ทธ๋“ค์€ ์™„์ „ํžˆ ๋‹ค๋ฅธ ๋ชฉํ‘œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉฐ, ๋‹น์‹ ์ด ์˜์‹ฌ ํ•  ์ˆ˜ ์žˆ๋“ฏ์ด, ๊ทธ๋“ค์€ ๋‹ค๋ฅธ ์ œํ•œ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

Expressions vs statements

์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ฐœ๋ฐœํ•œ๋‹ค๋ฉด, ์ผ์„ ํ‘œ์‹œํ•˜๋Š” ๊ฒƒ์ด ์ผ์˜ ํ•œ ๋ถ€๋ถ„ ์ผ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์‚ฌ์šฉ์ž ์ƒํ˜ธ ์ž‘์šฉ์„ ์ฒ˜๋ฆฌํ•ด์•ผํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์–ด์•ผ ํ•œ๋‹ค. ์ด๋ฅผ ํ—ˆ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๋ธŒ๋ผ์šฐ์ ธ๋Š” ๋‹น์‹ ์ด ๋ฐ›์„ ์ˆ˜ ์ œ์–ด ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ด๋ฒคํŠธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค. click, keyup, mousemove ๋“ฑ ... AngularJS 1.x๋Š” ์ด๋ฒคํŠธ ๋‹น ํ•˜๋‚˜์˜ ์ง€์‹œ๋ฌธ์„ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ , ng-click, ng-keyup, ng-mousemove ๋“ฑ ... Angular 2์—์„œ ์ด๊ฒƒ์„ ๋”์šฑ ๊ธฐ์–ตํ•˜๊ธฐ ์‰ฝ๊ณ  ๊ฐ„๋‹จํ•˜๊ฒŒ ์„ค๊ณ„ํ•˜์˜€๋‹ค.

์šฐ๋ฆฌ RacesComponent๋กœ ๋Œ์•„๊ฐ€์„œ, ์ด์ œ ํด๋ฆญํ–ˆ์„ ๋•Œ ๋ ˆ์ด์Šค๋ฅผ ํ‘œ์‹œ ํ•  ๋ฒ„ํŠผ์ด ํ•„์š”ํ•˜๋‹ค. ์ƒํ˜ธ์ž‘์šฉ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•  ๊ฒƒ์ด๋‹ค.

<button (click)="onButtonClick()">Click me!</button>

์œ„ ์˜ˆ์˜ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด onButtonClick () ๋ฉ”์†Œ๋“œ์˜ ํ˜ธ์ถœ์ด ํŠธ๋ฆฌ๊ฑฐ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

@Component({
  selector: 'ns-races',
  template: `
   <h2>Races</h2>
   <button (click)="refreshRaces()">Refresh the races list</button>
   <p>{{races.length}} races</p>
  `
})
export class RacesComponent {
  races: any = [];
  refreshRaces() {
   this.races = [{ name: 'London' }, { name: 'Lyon' }];
  }
}

๋งŒ์•ฝ ๋‹น์‹ ์˜ ๋ธŒ๋ผ์šฐ์ ธ์—์„œ ์‹œ๋„ํ•˜๋ ค๋ฉด, ๋‹น์‹ ์€ ์ฒ˜์Œ์— ์ด๋Ÿฌํ•œ ๊ตฌ์กฐ๋ฅผ ํ™•์ธํ•  ๊ฒƒ์ด๋‹ค.

<ponyracer-app>
  <h1>PonyRacer</h1>
  <ns-races>
   <h2>Races</h2>
   <button (click)="refreshRaces()">Refresh the races list</button>
   <p>0 races</p>
  </ns-races>
</ponyracer-app>

ํด๋ฆญํ•œ ์ดํ›„์— '0 races'๋Š” '2 races'๋กœ ๋ณ€ํ•  ๊ฒƒ์ด๋‹ค. ๋ช…๋ น๋ฌธ์€ ํ•จ์ˆ˜ ํ˜ธ์ถœ์ด ๋  ์ˆ˜๋„ ์žˆ์ง€๋งŒ ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ ๋ช…๋ น๋ฌธ ๋˜๋Š” ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ ๋ช…๋ น๋ฌธ์˜ ์—ฐ์†์ผ ์ˆ˜๋„ ์žˆ๋‹ค.

<button (click)="firstName = 'Cรฉdric'; lastName = 'Exbrayat'">
  Click to change name to Cรฉdric Exbrayat
</button>

๊ทธ๋Ÿฌ๋‚˜ ๋‚˜๋Š” ์ด๊ฒƒ์„ ๊ถŒ๊ณ ํ•˜์ง€๋Š” ์•Š๋Š”๋‹ค. ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋™์ž‘์„ ์บก์Šํ™” ํ•˜๋Š”๋ฐ ๋” ์ข‹์€ ๋ฐฉ๋ฒ•์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ฝ”๋“œ๋ฅผ ์œ ์ง€ ๊ด€๋ฆฌํ•˜๊ณ  ํ…Œ์ŠคํŠธํ•˜๊ธฐ๊ฐ€ ์‰ฌ์šฐ๋ฉฐ ๋ณด๊ธฐ๊ฐ€ ๋” ๋‹จ์ˆœํ•˜๋‹ค.

์ข‹์€ ์ ์€ ํ‘œ์ค€ DOM ์ด๋ฒคํŠธ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋ฐœ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋Š” ์‚ฌ์šฉ์ž ์ •์˜ ์ด๋ฒคํŠธ์—์„œ๋„ ์ž‘๋™ํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. Angular ๊ตฌ์„ฑ ์š”์†Œ ๋˜๋Š” ์›น ๊ตฌ์„ฑ ์š”์†Œ์—์„œ ๊ฐ€์ ธ์˜ฌ๊ฒƒ์ด๋‹ค. ๋‚˜์ค‘์— ๋งž์ถค ์ด๋ฒคํŠธ๋ฅผ ์‹œ์ž‘ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ดํŽด ๋ณด๊ฒ ๋‹ค.

์ž ์‹œ ๋™์•ˆ RacesComponent ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์ƒˆ๋กœ์šด ๊ฒฝ์ฃผ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ์„ ์•ฑ์— ์•Œ๋ฆฌ๊ธฐ ์œ„ํ•ด ๋งž์ถค ์ด๋ฒคํŠธ๋ฅผ ๋‚ด ๋ณด๋ƒˆ๋‹ค๊ณ  ๊ฐ€์ • ํ•ด ๋ณด์ž.

@Component({
  selector: 'ponyracer-app',
  template: '<h1>PonyRacer</h1> <ns-races (newRaceAvailable)="onNewRace()"></ns-races>'
})
export class PonyRacerAppComponent {
  onNewRace() {
   // add a flashy message for the user.
  }
}

๊ตฌ์„ฑ ์š”์†Œ์— newRaceAvailable์ด๋ผ๋Š” ์‚ฌ์šฉ์ž ์ง€์ • ์ด๋ฒคํŠธ๊ฐ€ ์žˆ๊ณ ์ด ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด PonyRacerAppComponentis์˜ onNewRace () ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜์—ˆ์Œ์„ ์‰ฝ๊ฒŒ ์•Œ ์ˆ˜ ์žˆ๋‹ค. Angular๋Š” ์š”์†Œ์™€ ํ•ด๋‹น ์š”์†Œ์˜ ์ด๋ฒคํŠธ๋ฅผ ์ˆ˜์‹ ํ•˜๋ฏ€๋กœ ๊ฑฐํ’ˆ์ด ๋ฐœ์ƒํ•˜๋Š” ์ด๋ฒคํŠธ์— ๋ฐ˜์‘ํ•œ๋‹ค. ํ…œํ”Œ๋ฆฟ์„ ๊ณ ๋ คํ•ด๋ณด๋„๋ก ํ•˜์ž.

<div (click)="onButtonClick()">
  <button>Click me!</button>
</div>

์‚ฌ์šฉ์ž๊ฐ€ div ์•ˆ์— ํฌํ•จ ๋œ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋”๋ผ๋„ onButtonClick () ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ์ด๋ฒคํŠธ๊ฐ€ ๊ฑฐํ’ˆ์„ ๋‚ด๋ฟœ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋‹น์‹ ์€๋ผ๋Š” ๋ฉ”์„œ๋“œ์—์„œ ์ด๋ฒคํŠธ์— ์•ก์„ธ์Šค ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋‹จ์ง€ $ event๋ฅผ ๋‹น์‹ ์˜ ๋ฉ”์†Œ๋“œ์— ๋„˜๊ฒจ ์ฃผ๋ฉด๋œ๋‹ค.

<div (click)="onButtonClick($event)">
  <button>Click me!</button>
</div>

๊ทธ๋Ÿฐ ๋‹ค์Œ ๊ตฌ์„ฑ ์š”์†Œ ํด๋ž˜์Šค์—์„œ ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌ ํ•  ์ˆ˜ ์žˆ๋‹ค.

onButtonClick(event) {
  console.log(event);
}

๊ธฐ๋ณธ์ ์œผ๋กœ ์ด๋ฒคํŠธ๋Š” ์ง€์†์ ์œผ๋กœ ๊ฑฐํ’ˆ์„ ๋‚ด๋ฉฐ ๊ฒฐ๊ตญ ๊ณ„์ธต์—์„œ ๋‹ค๋ฅธ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ๋ฅผ ํŠธ๋ฆฌ๊ฑฐํ•˜๊ฒŒ๋œ๋‹ค. ์ด ์ด๋ฒคํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ธฐ๋ณธ ๋™์ž‘์„ ๋ฐฉ์ง€ํ•˜๊ณ  ์›ํ•˜๋Š” ๊ฒฝ์šฐ ์ „ํŒŒ๋ฅผ ์ทจ์†Œ ํ•  ์ˆ˜ ์žˆ๋‹ค.

onButtonClick(event) {
  event.preventDefault();
  event.stopPropagation();
}

๋˜ ํ•˜๋‚˜์˜ ํŠน์ง•์€ ํ‚ค๋ณด๋“œ ์ด๋ฒคํŠธ๋ฅผ ๋ณด๋‹ค ์‰ฝ๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

<textarea (keydown.space)="onSpacePress()">Press space!</textarea>

spacekey๋ฅผ ๋ˆ„๋ฅผ ๋•Œ๋งˆ๋‹ค onSpacePress () ๋ฉ”์†Œ๋“œ๊ฐ€ ํ˜ธ์ถœ์žˆ๊ณ  (keydown.alt.space) ๋“ฑ์˜ ์ปค์Šคํ„ฐ๋งˆ์ด์ง•๋œ ์ฝค๋ณด๋ฅผ ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด ๋ถ€๋ถ„์„ ๊ฒฐ๋ก  ์ง“๊ธฐ ์œ„ํ•ด ๋‚˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํฐ ์ฐจ์ด๊ฐ€ ์žˆ์Œ์„ ์ง€์ ํ•˜๊ณ ์ž ํ•œ๋‹ค.

<component [property]="doSomething()"></component>
<component (event)="doSomething()"></component>

์ฒซ ๋ฒˆ์งธ ์†์„ฑ ๋ฐ”์ธ๋”ฉ์€ doSomething () ๊ฐ’์€ ์‹์ด๋ผ๊ณ  ๊ฐ ๋ณ€๊ฒฝ ๊ฒ€์ƒ‰์ฃผ๊ธฐ์—์„œ ํ‰๊ฐ€ ๋œ ์†์„ฑ์„ ์—…๋ฐ์ดํŠธ ํ•  ํ•„์š”๊ฐ€ ์žˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•œ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ๋‘ ๋ฒˆ์งธ์˜ ๊ฒฝ์šฐ๋Š” ์ด๋ฒคํŠธ ๋ฐ”์ธ๋”ฉ์€ doSomething () ๊ฐ’์€ ๋ฌธ์žฅ์ด๋ผ๊ณ  ์ด๋ฒคํŠธ๊ฐ€ ํŠธ๋ฆฌ๊ฑฐ ๋œ ๊ฒฝ์šฐ์—๋งŒ ํ‰๊ฐ€๋œ๋‹ค.

์ •์˜์— ๋”ฐ๋ฅด๋ฉด ๊ทธ๋“ค์€ ์™„์ „ํžˆ ๋‹ค๋ฅธ ๋ชฉํ‘œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉฐ, ๋‹น์‹ ์ด ์˜์‹ฌ ํ•  ์ˆ˜ ์žˆ๋“ฏ์ด, ๊ทธ๋“ค์€ ๋‹ค๋ฅธ ์ œํ•œ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

Local variables

Angular๊ฐ€ ๋ณ€์ˆ˜๋ฅผ ์ฐพ๊ธฐ ์œ„ํ•ด ๊ตฌ์„ฑ ์š”์†Œ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ณผ ๊ฒƒ์ด๋ผ๊ณ  ๋งํ•˜๋ฉด ๊ธฐ์ˆ ์ ์œผ๋กœ ์˜ฌ๋ฐ”๋ฅด์ง€ ์•Š๋‹ค. ์‹ค์ œ๋กœ ๊ตฌ์„ฑ ์š”์†Œ ์ธ์Šคํ„ด์Šค์™€ ๋กœ์ปฌ ๋ณ€์ˆ˜๋ฅผ ๊ฒ€์‚ฌํ•œ๋‹ค. ์ง€์—ญ ๋ณ€์ˆ˜๋Š” #syntax๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ…œํ”Œ๋ฆฟ์—์„œ ๋™์ ์œผ๋กœ ์„ ์–ธ ํ•  ์ˆ˜์žˆ๋Š” ๋ณ€์ˆ˜์ด๋‹ค.

์ž…๋ ฅ ๊ฐ’์„ ํ‘œ์‹œํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ณด์ž.

{% raw %}<input type="text" #name>
{{ name.value }}{% endraw %}

syntax๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ DOM ๊ฐœ์ฒด ์ธ HTMLInputElement๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๋กœ์ปฌ ๋ณ€์ˆ˜ ์ด๋ฆ„์„ ๋งŒ๋“ ๋‹ค.

์ด ๋กœ์ปฌ ๋ณ€์ˆ˜๋Š” ํ…œํ”Œ๋ฆฟ์˜ ์–ด๋Š ์œ„์น˜์—์„œ๋‚˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. value ์†์„ฑ์„ ๊ฐ€์ง€๋ฏ€๋กœ ์ด ์†์„ฑ์„ ๋ณด๊ฐ„ ๋œ ํ‘œํ˜„์‹์— ํ‘œ์‹œ ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋‚˜์ค‘์— ์ด ์˜ˆ์ œ๋กœ ๋Œ์•„ ์˜ค๊ฒ ๋‹ค.

์ง€์—ญ ๋ณ€์ˆ˜์˜ ๋˜ ๋‹ค๋ฅธ ์œ ์šฉํ•œ ์‚ฌ์šฉ๋ฒ•์€ ๋‹ค๋ฅธ ์š”์†Œ์—์„œ ์–ด๋–ค ์ข…๋ฅ˜์˜ ์•ก์…˜์„ ์‹คํ–‰ํ•˜๊ณ ์ž ํ•  ๋•Œ์ด๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ๋ฒ„ํŠผ์„ ํด๋ฆญ ํ•  ๋•Œ ์š”์†Œ์— ํฌ์ปค์Šค๋ฅผ ๋‘˜ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” AngularJS 1.x์—์„œ ์‚ฌ์šฉ์ž ์ง€์ • ์ง€์‹œ๋ฌธ์„ ์ž‘์„ฑํ•ด์•ผํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์•ฝ๊ฐ„ ๋ฒˆ๊ฑฐ๋กœ์šด ์ ์ด ์žˆ์—ˆ๋‹ค.

focus () ๋ฉ”์†Œ๋“œ๋Š” DOM API์˜ ํ‘œ์ค€ ๋ถ€๋ถ„์ด๋ฉฐ์ด๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๊ณ  ์ง€์—ญ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด Angular 2๋ฅผ ์‰ฝ๊ฒŒ ์ ‘๊ทผ ํ•  ์ˆ˜ ์žˆ๋‹ค.

<input type="text" #name>
<button (click)="name.focus()">Focus the input</button>

๋˜ํ•œ ์‚ฌ์šฉ์ž ์ •์˜ ๊ตฌ์„ฑ ์š”์†Œ (์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์—์„œ ์ž‘์„ฑํ•œ ๊ตฌ์„ฑ ์š”์†Œ, ๋‹ค๋ฅธ ํ”„๋กœ์ ํŠธ์—์„œ ๊ฐ€์ ธ์˜จ ๊ตฌ์„ฑ ์š”์†Œ ๋˜๋Š” ์‹ค์ œ ์›น ๊ตฌ์„ฑ ์š”์†Œ)์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

<google-youtube #player></google-youtube>
<button (click)="player.play()">Play!</button>

์—ฌ๊ธฐ์—์„œ ๋ฒ„ํŠผ์€ ๊ตฌ์„ฑ ์š”์†Œ์˜ ๋™์˜์ƒ ์žฌ์ƒ์„ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๊ฒƒ์€ ์‹ค์ œ๋กœ Polymer๋กœ ์ž‘์„ฑ๋œ ์‹ค์ œ ์›น ๊ตฌ์„ฑ ์š”์†Œ์ด๋‹ค! ์ด ๊ตฌ์„ฑ ์š”์†Œ์—๋Š” ๋‹จ์ถ”๋ฅผ ํด๋ฆญ ํ•  ๋•Œ Angular๊ฐ€ ํ˜ธ์ถœํ•˜๋Š” play () ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ๋‹ค.

์ง€์—ญ ๋ณ€์ˆ˜์—๋Š” ๋ช‡ ๊ฐ€์ง€ ์œ ์Šค ์ผ€์ด์Šค๊ฐ€ ์žˆ์œผ๋ฉฐ, ์ ์ง„์ ์œผ๋กœ ์‚ดํŽด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ทธ ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋ฐ”๋กœ ๋‹ค์Œ ์„น์…˜์— ์„ค๋ช…๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

Structural directives

702/5000 ์ด์ œ ์šฐ๋ฆฌ์˜ RacesComponent๋Š” ์—ฌ์ „ํžˆ ๋ ˆ์ด์Šค๋ฅผ ํ‘œ์‹œํ•˜์ง€ ์•Š๋Š”๋‹ค. Angular 2์˜ "์ ์ ˆํ•œ ๋ฐฉ๋ฒ•"์€ ๊ฐ ๋ ˆ์ด์Šค๋ฅผ ํ‘œ์‹œํ•˜๋Š” ๋˜ ๋‹ค๋ฅธ ๊ตฌ์„ฑ ์š”์†Œ ์ธ RaceComponent๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค. ์•ฝ๊ฐ„ ๋” ๊ฐ„๋‹จํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ„๋‹จํ•œ ๋ชฉ๋ก์„ ์‚ฌ์šฉํ•  ๊ฒƒ์ด๋‹ค.

์†์„ฑ ๋ฐ ์ด๋ฒคํŠธ ๋ฐ”์ธ๋”ฉ์€ ํ›Œ๋ฅญํ•˜์ง€๋งŒ ์ปฌ๋ ‰์…˜์„ ๋ฐ˜๋ณตํ•˜๊ณ  ํ•ญ๋ชฉ ๋‹น ์š”์†Œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์ด DOM ๊ตฌ์กฐ๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜๋Š” ์—†๋‹ค. ์ด๋ฅผ ์œ„ํ•ด์„œ๋Š” ๊ตฌ์กฐ ์ง€์‹œ๋ฌธ์„ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค. Angular์˜ ์ง€์‹œ๋ฌธ์€ ์‹ค์ œ๋กœ ๊ตฌ์„ฑ ์š”์†Œ์™€ ๋น„์Šทํ•˜์ง€๋งŒ ํ…œํ”Œ๋ฆฟ์ด ์—†๋‹ค. ์š”์†Œ์— ๋น„ํ—ค์ด๋น„์–ด๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋œ๋‹ค. Angular 2์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ตฌ์กฐ ์ง€์‹œ๋ฌธ์€ HTML ์‚ฌ์–‘์˜ ํ‘œ์ค€ ํƒœ๊ทธ ์ธ template ์š”์†Œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

<template>
  <div>Races list</div>
</template>

์—ฌ๊ธฐ์— ํ…œํ”Œ๋ฆฟ์„ ์ •์˜ํ•˜๊ณ  ๊ฐ„๋‹จํ•œ div๋ฅผ ํ‘œ์‹œํ•œ๋‹ค. ๋ธŒ๋ผ์šฐ์ ธ๊ฐ€ ํ‘œ์‹œํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ๋‹จ์ผ๋กœ๋Š” ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํ•˜๋‚˜์˜ 'template'์š”์†Œ๋ฅผ ๋ทฐ์— ์ถ”๊ฐ€ํ•œ๋‹ค๋ฉด Angular 2 ๋Š” ํ•ด๋‹น ๋‚ด์šฉ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ตฌ์กฐ์  ์ง€์‹œ๋ฌธ์—๋Š” ๋‚ด์šฉ์„ ํ‘œ์‹œํ•˜๊ฑฐ๋‚˜ ํ‘œ์‹œํ•˜์ง€ ์•Š๊ณ  ๋ฐ˜๋ณตํ•˜๋Š” ๋“ฑ์˜ ๊ฐ„๋‹จํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ ํ•  ์ˆ˜ ์žˆ๋‹ค.

NgIf

์กฐ๊ฑด์ด ์ผ์น˜ํ•˜๋Š” ๊ฒฝ์šฐ์—๋งŒ ํ…œํ”Œ๋ฆฟ์„ ์‚ฌ์šฉํ•˜๊ธธ ์›ํ•œ๋‹ค๋ฉด ngIf๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

<template [ngIf]="races.length > 0">
  <div><h2>Races</h2></div>
</template>

์—ฌ๊ธฐ์„œ ํ…œํ”Œ๋ฆฟ์€ race๊ฐ€ ์ ์–ด๋„ ํ•˜๋‚˜์˜ ์š”์†Œ๋ฅผ ๊ฐ€์ง€๊ณ ์žˆ์„ ๋•Œ, ์ฆ‰ race๊ฐ€ ์žˆ๋‹ค๋ฉด ์ธ์Šคํ„ด์Šคํ™” ๋  ๊ฒƒ์ด๋‹ค. ์ด ๊ตฌ๋ฌธ์€ ์•ฝ๊ฐ„ ๊ธธ๊ธฐ ๋•Œ๋ฌธ์— ์งง์€ ๋ฒ„์ „์œผ๋กœ ๋ณด์—ฌ์ฃผ์—ˆ๋‹ค.

<div *ngIf="races.length > 0"><h2>Races</h2></div>

๊ตฌ๋ฌธ์€ *๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌ์กฐ ์ง€์‹œ๋ฌธ์ž„์„ ๋‚˜ํƒ€๋‚ธ๋‹ค. ngIf ๋˜๋Š” ๊ฒฝ์ฃผ ๊ฐ’์ด ๋ณ€๊ฒฝ ๋  ๋•Œ๋งˆ๋‹ค div๊ฐ€ ํ‘œ์‹œ๋˜์ง€ ์•Š๋Š”๋‹ค. ๋” ์ด์ƒ ๊ฒฝ์ฃผ๊ฐ€ ์—†์œผ๋ฉด div๋Š” ์‚ฌ๋ผ์งˆ๊ฒƒ์ด๋‹ค. ํ”„๋ ˆ์ž„ ์›Œํฌ์—์„œ ์ œ๊ณต๋˜๋Š” ์ง€์‹œ๋ฌธ์€ ์ด๋ฏธ ์‚ฌ์ „ ๋กœ๋“œ๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ @Componentdecorator์˜ ์ง€์‹œ์–ด ์†์„ฑ์—์„œ NgIf๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ  ์„ ์–ธ ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.

import { Component } from '@angular/core';
@Component({
  selector: 'ns-races',
  template: `<div *ngIf="races.length > 0"><h2>Races</h2></div>`
})
export class RacesComponent {
  races: Array<any> = [];
}

NgFor

์‹ค์ œ ๋ฐ์ดํ„ฐ๋กœ ์ž‘์—…ํ•˜๋ฉด ํ•„์—ฐ์ ์œผ๋กœ ๋ฌด์–ธ๊ฐ€์˜ ๋ชฉ๋ก์„ ํ‘œ์‹œํ•˜๊ฒŒ ๋œ๋‹ค. NgFor๋Š” ๋งค์šฐ ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉ ๋œ๋‹ค. ์ปฌ๋ ‰์…˜์˜ ํ•ญ๋ชฉ ๋‹น ํ•˜๋‚˜์˜ ํ…œํ”Œ๋ฆฟ์„ ์ธ์Šคํ„ด์Šคํ™” ํ•  ์ˆ˜ ์žˆ๋‹ค. ์šฐ๋ฆฌ์˜ RacesComponent ๊ตฌ์„ฑ ์š”์†Œ์—๋Š” ์•„๋งˆ ์ถ”์ธก ํ•  ์ˆ˜ ์žˆ๋“ฏ์ด ํ‘œ์‹œ ํ•  ๊ฒฝ์ฃผ์˜ ๋ฐฐ์—ด ์ธ ํ•„๋“œ ๊ฒฝ์ฃผ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

import { Component } from '@angular/core';
@Component({
  selector: 'ns-races',
  template: `<div *ngIf="races.length > 0">
  <h2>Races</h2>
  <ul>
   <li *ngFor="let race of races">{{race.name}}</li>
  </ul>
  </div>`
})
export class RacesComponent {
  races: Array<any> = [{ name: 'London' }, { name: 'Lyon' }];
}

์ด์ œ ์šฐ๋ฆฌ ์ปฌ๋ ‰์…˜์—๋Š” ํ•ญ๋ชฉ ๋‹น ํ•˜๋‚˜์˜ li ํƒœ๊ทธ๊ฐ€์žˆ๋Š” ๋ฉ‹์ง„ ๋ชฉ๋ก์ด ์žˆ๋‹ค.

<ul>
  <li>London</li>
  <li>Lyon</li>
</ul>

NgFor๊ฐ€ microsyntax๋ผ๊ณ  ํ•˜๋Š” ํŠน์ • ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค.

<ul>
  <li *ngFor="let race of races">{{race.name}}</li>
</ul>
<ul>
  <template ngFor let-race [ngForOf]="races">
   {% raw %}<li>{{race.name}}</li>{% endraw %}
  </template>
</ul>

์—ฌ๊ธฐ์„œ ๋‹น์‹ ์ด ์ธ์ง€ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ๋“ค์ด ์žˆ๋‹ค.

  • template ์š”์†Œ๋Š” template ์•ˆ์— ์žˆ๋Š” ์š”์†Œ๋“ค์„ ์ •์˜ํ•œ๋‹ค.

  • NgFor ์ง€์‹œ๋ฌธ์ด ์ ์šฉ๋˜์–ด ์žˆ๋‹ค.

  • NgForOf ์š”์†Œ๋Š” ํ‘œํ˜„ํ•  ์ง‘ํ•ฉ์— ๋Œ€ํ•œ ์ •์˜ ์ด๋‹ค.

  • race ๋ณ€์ˆ˜๋Š” ํ˜„์žฌ ์š”์†Œ๋ฅผ ๋ฐ˜์˜ํ•˜๊ณ  ํ•จ์ถฅ๋œ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ํ—ˆ์šฉํ•œ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์ด ๋ชจ๋“  ๊ฒƒ์„ ๊ธฐ์–ตํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค๋Š” ์งง์€ ํ˜•์‹์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒŒ ๋” ํšจ๊ณผ์ ์ด๋‹ค.

<ul>
  {% raw %}<li *ngFor="let race of races">{{race.name}}</li>{% endraw %}
</ul>

ํ˜„์žฌ ์š”์†Œ์˜ ์ƒ‰์ธ์— ๋ฐ”์ธ๋“œ ๋œ ๋‹ค๋ฅธ ์ง€์—ญ ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธ ํ•  ์ˆ˜ ์žˆ๋‹ค.

<ul>
  {% raw %}<li *ngFor="let race of races; let i=index">{{i}} - {{race.name}}</li>{% endraw %}
</ul>

์ง€์—ญ ๋ณ€์ˆ˜ i๋Š” 0์—์„œ ์‹œ์ž‘ํ•˜์—ฌ ํ˜„์žฌ ์š”์†Œ์˜ ์ธ๋ฑ์Šค๋ฅผ ๋ฐ›๋Š”๋‹ค.

<ul>
  <li>0 - London</li>
  <li>1 - Lyon</li>
</ul>

์œ ์šฉ ํ•  ์ˆ˜์žˆ๋Š” ๋‹ค๋ฅธ ๋‚ด ๋ณด๋‚ธ ๋ณ€์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. โ€ข even, ์š”์†Œ๊ฐ€ ์ง์ˆ˜ ์ธ๋ฑ์Šค๋ฅผ ๊ฐ–๋Š” ๊ฒฝ์šฐ ์ฐธ์ธ ๋ถ€์šธ ๊ฐ’์ด๋‹ค. โ€ข odd, ๋ถ€์šธ ๊ฐ’์€ ์š”์†Œ์— ํ™€์ˆ˜ ์ƒ‰์ธ์ด์žˆ๋Š” ๊ฒฝ์šฐ true์ด๋‹ค. โ€ข first : ์š”์†Œ๊ฐ€ ์ปฌ๋ ‰์…˜์˜ ์ฒซ ๋ฒˆ์งธ ์š”์†Œ ์ธ ๊ฒฝ์šฐ ์ฐธ์ธ ๋ถ€์šธ๊ฐ’ ์ด๋‹ค. โ€ข last : ์š”์†Œ๊ฐ€ ์ปฌ๋ ‰์…˜์˜ ๋งˆ์ง€๋ง‰ ์š”์†Œ ์ธ ๊ฒฝ์šฐ ์ฐธ์ธ ๋ถ€์šธ๊ฐ’ ์ด๋‹ค.

NgSwtich

์ด๋ฆ„์—์„œ ์ง์ž‘ํ•  ์ˆ˜ ์žˆ๋“ฏ์ด ์ง€์‹œ๋ฌธ์€ ์กฐ๊ฑด์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ํ…œํ”Œ๋ฆฟ์„ ์ „ํ™˜ ํ•  ์ˆ˜์žˆ๊ฒŒ ํ•ด์ค€๋‹ค.

<div [ngSwitch]="messageCount">
  <p *ngSwitchCase="0">You have no message</p>
  <p *ngSwitchCase="1">You have a message</p>
  <p *ngSwitchDefault>You have some messages</p>
</div>

๋ณด์‹œ๋‹ค์‹œํ”ผ ngSwitch๋Š” ์กฐ๊ฑด์„ ์ทจํ•˜๊ณ  ngSwitchCase๋Š” ๊ฐ€๋Šฅํ•œ ๊ฐ’์„ ์ทจํ•œ๋‹ค. ์ผ์น˜ํ•˜๋Š” ๊ฐ’์ด ์—†์„ ๊ฒฝ์šฐ ngSwitchDefault๋ฅผ ํ‘œ์‹œ ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

Other template directives

๋‹ค๋ฅธ ๋‘ ๊ฐœ์˜ ์ง€์‹œ๋ฌธ์€ ํ…œํ”Œ๋ฆฟ์„ ์ž‘์„ฑํ•  ๋•Œ ์œ ์šฉ ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๋ฐฉ๊ธˆ ๋ณธ ๊ฒƒ๊ณผ ๊ฐ™์€ ๊ตฌ์กฐ ์ง€์‹œ๋ฌธ์€ ์•„๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ง€์‹œ๋ฌธ์€ ํ‘œ์ค€ ์ง€์‹œ๋ฌธ์ด๋‹ค.

NgStyle

์šฐ๋ฆฌ๋Š” ์ด๋ฏธ ์šฐ๋ฆฌ๊ฐ€ ์š”์†Œ์˜ ์Šคํƒ€์ผ์— ๋”ฐ๋ผ ํ–‰๋™ ํ•  ์ˆ˜ ์žˆ์Œ์„ ๋ณด์•˜๋‹ค.

<p [style.color]="foreground">Friendship is Magic</p>

๋™์‹œ์— ์—ฌ๋Ÿฌ ์Šคํƒ€์ผ์„ ์„ค์ •ํ•ด์•ผํ•˜๋Š” ๊ฒฝ์šฐ ngStyle ์ง€์‹œ๋ฌธ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

{% raw %}<div [ngStyle]="{fontWeight: fontWeight, color: color}">I've got style</div>{% endraw %}

์ง€์‹œ๋ฌธ์€ ํ‚ค๊ฐ€ ์Šคํƒ€์ผ์„ ์„ค์ •ํ•  ๊ฐ์ฒด๋ฅผ ๊ธฐ๋Œ€ํ•œ๋‹ค. ํ‚ค๋Š” camelCase (fontWeight) ๋˜๋Š” ๋Œ€์‹œ ( 'font-weight') ์ค‘ ํ•˜๋‚˜ ์ผ ์ˆ˜ ์žˆ๋‹ค.

NgClass

๊ฐ™์€ ๋ฌธ๋งฅ์œผ๋กœ ํด๋ž˜์Šค ์ง€์‹œ์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์š”์†Œ๋ฅผ ๋™์ ์œผ๋กœ ํด๋ž˜์Šค์— ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์ œ๊ฑฐ ํ•  ์ˆ˜ ์žˆ๋‹ค. ์Šคํƒ€์ผ์€ ์†์„ฑ ๋ฐ”์ธ๋”ฉ์„ ์‚ฌ์šฉํ•˜์—ฌ ํ•˜๋‚˜์˜ ํด๋ž˜์Šค๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

<div [class.awesome-div]="isAnAwesomeDiv()">I've got style</div>

๋˜๋Š” ์—ฌ๋Ÿฌ ํ•ญ๋ชฉ์„ ๋™์‹œ์— ์„ค์ •ํ•˜๋ ค๋Š” ๊ฒฝ์šฐ ngClass๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

{% raw %} <div [ngClass]="{'awesome-div': isAnAwesomeDiv(), 'colored-div': isAColoredDiv()}">I've got style</div>{% endraw %}

Canonical syntax

์šฐ๋ฆฌ๊ฐ€ ๋ณธ ๋ชจ๋“  ๊ตฌ๋ฌธ์€ ํ‘œ์ค€ ๊ตฌ๋ฌธ์ด๋ผ๋Š”๋ณด๋‹ค ๊ธด ์ƒ์‘์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. ์ด๊ฒƒ์€ ์ฃผ๋กœ ์„œ๋ฒ„ ์ธก์˜ ํ…œํ”Œ๋ฆฟ ์‹œ์Šคํ…œ์ด [] ๋˜๋Š” () ๊ตฌ๋ฌธ์— ๋ฌธ์ œ๊ฐ€์žˆ์„ ๊ฒฝ์šฐ ๋˜๋Š”, () *๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜์—†๋Š” ๊ฒฝ์šฐ์— ์œ ์šฉํ•˜๋‹ค.

์†์„ฑ ๋ฐ”์ธ๋”ฉ์„ ์„ ์–ธํ•˜๋ ค๋Š” ๊ฒฝ์šฐ ๋‹ค์Œ์„ ์ˆ˜ํ–‰ ํ•  ์ˆ˜ ์žˆ๋‹ค.

<ns-pony [name]="pony.name"></ns-pony>

๋˜๋Š” ์ •๊ทœ ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜์—ฌ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

<ns-pony bind-name="pony.name"></ns-pony>

์ด๋ฒคํŠธ ํ• ๋‹น๋„ ๋งˆ์ฐฌ๊ฐ€์ง€ ์ด๋‹ค.

<button (click)="onButtonClick()">Click me!</button>

๋˜๋Š” ์ •๊ทœ ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜์—ฌ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

<button on-click="onButtonClick()">Click me!</button>
<input type="text" ref-name>
<button on-click="name.focus()">Focus the input</button>
<input type="text" #name>
<button (click)="name.focus()">Focus the input</button>

Summary

Angular 2 ํ…œํ”Œ๋ฆฟ ์‹œ์Šคํ…œ์€ HTML์˜ ๋™์  ๋ถ€๋ถ„์„ ํ‘œํ˜„ํ•˜๋Š” ๊ฐ•๋ ฅํ•œ ๊ตฌ๋ฌธ์„ ์ œ๊ณตํ•œ๋‹ค. ๋ฐ์ดํ„ฐ์™€ ์†์„ฑ ๋ฐ”์ธ๋”ฉ, ์ด๋ฒคํŠธ ๋ฐ”์ธ๋”ฉ ๋ฐ ํ…œํ”Œ๋ฆฟ ๊ด€๋ จ ๋ฌธ์ œ๋ฅผ ๋ช…ํ™•ํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ฐ๊ฐ ๊ณ ์œ  ํ•œ ์‹ฌ๋ณผ์ด ์žˆ๋‹ค.

โ€ข ๋ณด๊ฐ„์„ ์œ„ํ•œ โ€ข ์†์„ฑ ๋ฐ”์ธ๋”ฉ์„ ์œ„ํ•œ [] โ€ข ์ด๋ฒคํŠธ ๋ฐ”์ธ๋”ฉ์„ ์œ„ํ•œ () โ€ข ๋ณ€์ˆ˜ ์„ ์–ธ์„ ์œ„ํ•œ #for โ€ข ๊ตฌ์กฐ ์ง€์‹œ๋ฌธ์„ ์œ„ํ•œ *

๋‹ค๋ฅธ ํ”„๋ ˆ์ž„ ์›Œํฌ์ฒ˜๋Ÿผ ํ‘œ์ค€ ์›น ๊ตฌ์„ฑ ์š”์†Œ์™€ ์ƒํ˜ธ ์ž‘์šฉํ•  ์ˆ˜์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•œ๋‹ค. ๋‹ค์–‘ํ•œ ์˜๋ฏธ ์‚ฌ์ด์— ๋ชจํ˜ธ์„ฑ์ด ์—†์œผ๋ฏ€๋กœ ํ…œํ”Œ๋ฆฟ๊ณผ IDE๊ฐ€ ์ ์ง„์ ์œผ๋กœ ํ–ฅ์ƒ๋˜์–ด ํ…œํ”Œ๋ฆฟ์—์„œ ์ž‘์„ฑํ•œ ๋‚ด์šฉ์— ๋Œ€ํ•œ ์˜๋ฏธ์žˆ๋Š” ๊ฒฝ๊ณ ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค. ์ด ๋ชจ๋“  ๊ธฐํ˜ธ๋Š” ์ •์‹ ๋ฒ„์ „์˜ ์งง์€ ๋ฒ„์ „์œผ๋กœ, ์›ํ•˜๋Š” ๊ฒฝ์šฐ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ์ด ๊ตฌ๋ฌธ์„ ์œ ์ฐฝํ•˜๊ฒŒํ•˜๋ ค๋ฉด ์‹œ๊ฐ„์ด ์ข€ ๊ฑธ๋ฆฌ ๊ฒ ์ง€๋งŒ ๊ณง ์†๋„๊ฐ€ ๋นจ๋ผ์ง„๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ์ฝ๊ณ  ์“ฐ๋Š” ๊ฒƒ์ด ์‰ฝ๋‹ค. ๊ณ„์† ์ง„ํ–‰ํ•˜๊ธฐ ์ „์— ์ „์ฒด ์˜ˆ์ œ๋ฅผ ์‚ดํŽด ๋ณด๋„๋ก ํ•˜์ž.

pony ๋ชฉ๋ก์„ ํ‘œ์‹œํ•˜๋Š” PoniesComponent ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ์‹ถ๋‹ค. ๊ฐ ์กฐ๋ž‘๋ง์€ PonyComponent ๊ตฌ์„ฑ ์š”์†Œ๋กœ ๋‚˜ํƒ€๋‚ด์•ผํ•˜์ง€๋งŒ ๊ตฌ์„ฑ ์š”์†Œ์— ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•„์ง ๋ณด์ง€ ๋ชปํ–ˆ๋‹ค. ์ด์ œ๋Š” ๊ฐ„๋‹จํ•œ ๋ชฉ๋ก์„ ๋ณด์—ฌ์ค„ ๊ฒƒ์ด๋‹ค. ๋ชฉ๋ก์€ ํ‘œ์‹œ๋˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ์—๋งŒ ํ‘œ์‹œ๋˜์–ด์•ผ ํ•œ๋‹ค. ๋น„์–ด์žˆ๋Š”, ๊ทธ๋ฆฌ๊ณ  ๋‚ด ๋ชฉ๋ก์˜ ์ง์ˆ˜ ๋ผ์ธ์— ๋Œ€ํ•œ ๋ช‡ ๊ฐ€์ง€ ์ƒ‰์ƒ์„ ๊ฐ–๊ณ  ์‹ถ๋‹ค. ๋งˆ์ง€๋ง‰์œผ๋กœ ๋ฒ„ํŠผ ํด๋ฆญ์œผ๋กœ ๋ชฉ๋ก์„ ์ƒˆ๋กœ ๊ณ ์นจํ•˜๊ณ  ์‹ถ๋‹ค.

import { Component } from '@angular/core';
@Component({
  selector: 'ns-ponies',
  template: ``
})
export class PoniesComponent {
}

์ด์ „ ์žฅ์—์„œ ํ…Œ์ŠคํŠธ ํ•œ PonyRacerAppComponent ๊ตฌ์„ฑ ์š”์†Œ์— ์ถ”๊ฐ€ ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋ฅผ ๊ฐ€์ ธ ์™€์„œ ์ง€์‹œ๋ฌธ์— ์ถ”๊ฐ€ํ•˜๊ณ  </ ns-ponies> ํƒœ๊ทธ๋ฅผ ํ…œํ”Œ๋ฆฟ์— ์‚ฝ์ž…ํ•ด์•ผ ํ•œ๋‹ค.

import { Component } from '@angular/core';
@Component({
  selector: 'ns-ponies',
  template: ``
})
export class PoniesComponent {
  ponies: Array<any> = [{ name: 'Rainbow Dash' }, { name: 'Pinkie Pie' }];
}

์šฐ๋ฆฌ๋Š” Ngfor๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ณด์—ฌ์ค„๊ฒƒ์ด๋‹ค.

import { Component } from '@angular/core';
@Component({
  selector: 'ns-ponies',
  template: `<ul>
   <li *ngFor="let pony of ponies">{{pony.name}}</li>
  </ul>`
})
export class PoniesComponent {
  ponies: Array<any> = [{ name: 'Rainbow Dash' }, { name: 'Pinkie Pie' }];
}

์ถ”๊ฐ€ ๋ฒ„ํŠผ๋„ ์ถ”๊ฐ€ํ•ด๋ณด์ž.

import { Component } from '@angular/core';
@Component({
  selector: 'ns-ponies',
  template: `<button (click)="refreshPonies()">Refresh</button>
  <ul>
   <li *ngFor="let pony of ponies">{{pony.name}}</li>
  </ul>`
})
export class PoniesComponent {
  ponies: Array<any> = [{ name: 'Rainbow Dash' }, { name: 'Pinkie Pie' }];
  refreshPonies() {
   this.ponies = [{ name: 'Fluttershy' }, { name: 'Rarity' }];
  }
}
import { Component } from '@angular/core';
@Component({
  selector: 'ns-ponies',
  template: `<button (click)="refreshPonies()">Refresh</button>
  <ul>
   <li *ngFor="let pony of ponies; let isEven=even"
   [style.color]="isEven ? 'green' : 'black'">
   {{pony.name}}
   </li>
  </ul>`
})
export class PoniesComponent {
  ponies: Array<any> = [{ name: 'Rainbow Dash' }, { name: 'Pinkie Pie' }];
  refreshPonies() {
   this.ponies = [{ name: 'Fluttershy' }, { name: 'Rarity' }];
  }
}

๋ณด์‹œ๋‹ค์‹œํ”ผ, ์šฐ๋ฆฌ๋Š” ํ…œํ”Œ๋ฆฟ ๊ตฌ๋ฌธ์˜ ๋ชจ๋“  ๋ฒ”์œ„๋ฅผ ์‚ฌ์šฉํ–ˆ์œผ๋ฉฐ, ์šฐ๋ฆฌ๋Š” ์™„๋ฒฝํ•˜๊ฒŒ ์ž‘๋™ํ•˜๋Š” ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. ์šฐ๋ฆฌ์˜ ๋ฐ์ดํ„ฐ๋Š” ์—ฌ์ „ํžˆ ํ•˜๋“œ ์ฝ”๋“œ๋˜์–ด ์žˆ๋‹ค. ๊ณง ์„œ๋น„์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ€์ ธ ์˜ค๋Š” ๋ฐฉ๋ฒ•์„ ์‚ดํŽด ๋ณด์ž! ์ด๊ฒƒ์€ ์˜์กด์„ฑ ์ฃผ์ž…์„ ๋จผ์ € ๋ฐฐ์šฐ๋ฏ€๋กœ HTTP ์„œ๋น„์Šค๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ์„ ์˜๋ฏธํ•œ๋‹ค.

Reference URL

Last updated