CHAPTER 7. Pipes

Pied piper

๋•Œ๋กœ๋Š” ๊ธฐ์กด ๋ฐ์ดํ„ฐ๊ฐ€ ๋ทฐ์— ํ‘œ์‹œ ํ•  ๋ฐ์ดํ„ฐ๊ฐ€ ์•„๋‹ ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ข…์ข… ํ•„ํ„ฐ๋ฅผ ๋ณ€ํ™˜ํ•˜๊ณ , ํ•„ํ„ฐ๋ฅผ ๊ฑธ๊ณ , ํ•„ํ„ฐ๋ฅผ ์ œํ•œํ•˜๋Š” ๋“ฑ์˜ ์ž‘์—…์„ ์›ํ•œ๋‹ค. AngularJS 1.x์—๋Š” 'ํ•„ํ„ฐ'๋ผ๊ณ ํ•˜๋Š” ์ด๋ฆ„์ด ๋งค์šฐ ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉ๋˜์—ˆ๋‹ค.

ํŒŒ์ดํ”„๋Š” HTML ๋˜๋Š” ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ ์ฝ”๋“œ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค๊ณ  ์šฐ๋ฆฌ๊ฐ€ ๊ทธ๊ฒƒ์„ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ๋ณด์ž.

Json

JsonPipe๋Š” ๊ฐœ๋ฐœ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์—์„œ๋Š” ๋ณ„๋กœ ์œ ์šฉํ•˜์ง€ ์•Š์ง€๋งŒ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์„ ๋””๋ฒ„๊น… ํ•  ๋•Œ๋Š” ๋งค์šฐ ์œ ์šฉํ•˜๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ์ด ํŒŒ์ดํ”„๋Š” JSON.stringify ()๋ฅผ ๋ฐ์ดํ„ฐ์— ์ ์šฉํ•œ๋‹ค. ๊ตฌ์„ฑ ์š”์†Œ์— ์ผ๋ถ€ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ pony ๋ฐฐ์—ด์„ ์˜ˆ๋กœ ๋“ค์ž๋ฉด, ๋‚ด๋ถ€์— ๋ฌด์—‡์ด ์žˆ๋Š”์ง€ ์‹ ์†ํ•˜๊ฒŒ ํ™•์ธํ•˜๋ ค๋Š” ๊ฒฝ์šฐ, ๋‹น์‹ ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒƒ์„ ์‹œ๋„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

<p>{% raw %}{{ ponies }}{% endraw %}</p>

์šด์ด ์ข‹์œผ๋ฉด [object object]๊ฐ€ ํ‘œ์‹œ ๋  ๊ฒƒ์ด๋‹ค. ํ•˜์ง€๋งŒ JsonPipe๋Š” ์šฐ๋ฆฌ๋ฅผ ๊ตฌํ•˜๊ธฐ ์œ„ํ•ด ์—ฌ๊ธฐ์— ์žˆ๊ณ  ์–ด๋–ค ์‹ ์œผ๋กœ๋“  HTML์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

<p>{% raw %}{{ ponies | json }}{% endraw %}</p>

๊ทธ๋ฆฌ๊ณ  ๊ทธ๊ฒƒ์€ ๊ฐœ์ฒด์˜ JSON ํ‘œํ˜„์„ ํ‘œ์‹œํ•œ๋‹ค.

<p>[ { "name": "Rainbow Dash" }, { "name": "Pinkie Pie" } ]</p>

ํŒŒ์ดํ”„๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋ฐ์ดํ„ฐ ๋‹ค์Œ์— ํŒŒ์ดํ”„ (|) ๋ฌธ์ž๋ฅผ ์ถ”๊ฐ€ ํ•œ ๋‹ค์Œ ์‚ฌ์šฉํ•  ํŒŒ์ดํ”„์˜ ์ด๋ฆ„์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค. ํ‘œํ˜„์‹์ด ํ‰๊ฐ€๋˜๊ณ  ๊ฒฐ๊ณผ๊ฐ€ ํŒŒ์ดํ”„๋ฅผ ํ†ต๊ณผํ• ๊ฒƒ์ด๋‹ค. ์—ฌ๋Ÿฌ ํŒŒ์ดํ”„๋ฅผ ์ฐจ๋ก€๋กœ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

<p>{% raw %}{{ ponies | slice:0:2 | json }}{% endraw %}</p>

์šฐ๋ฆฌ๋Š” ์Šฌ๋ผ์ด์Šค ํŒŒ์ดํ”„๋กœ ๋Œ์•„๊ฐˆ ๊ฒƒ์ด์ง€๋งŒ ์Šฌ๋ผ์ด์Šค ํŒŒ์ดํ”„๋ฅผ ์—ฐ๊ฒฐ ํ•œ ๋‹ค์Œ json์„ ์—ฐ๊ฒฐํ•˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. "

"๋ณด๊ฐ„ ํ‘œํ˜„์‹์ด๋‚˜ ์†์„ฑ ํ‘œํ˜„์‹์—์„œ๋Š” ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ด๋ฒคํŠธ ๋ฌธ์—์„œ๋Š” ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.

<p [textContent]="ponies | json"></p>

์˜์กด์„ฑ ์‚ฝ์ž…์„ ํ†ตํ•ด ์ฝ”๋“œ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

import { Component } from '@angular/core';
// you need to import the pipe you want to use
import { JsonPipe } from '@angular/common';
@Component({
  selector: 'ns-ponies',
  template: `<p>{% raw %}{{poniesAsJson}}{% endraw %}</p>`
})
export class PoniesComponent {
  ponies: Array<any> = [{ name: 'Rainbow Dash' }, { name: 'Pinkie Pie' }];
  poniesAsJson: string;
  // inject the Pipe you want
  constructor(jsonPipe: JsonPipe) {
   // and then call the transform method on it
   this.poniesAsJson = jsonPipe.transform(this.ponies);
  }
}

๊ทธ๋Ÿฌ๋‚˜ ์กฐ์‹ฌ ํ•ด์•ผํ•œ๋‹ค : ํŒŒ์ดํ”„๋Š” @NgModule (๋˜๋Š” @Component)์˜ provider์— ์ถ”๊ฐ€๋˜์–ด์•ผ ํ•œ๋‹ค. ์ด๊ฒƒ์€ ๋ชจ๋“  ํŒŒ์ดํ”„์—์„œ ๋™์ผํ•˜๋ฏ€๋กœ ๋ณด๊ฐ„๋ฒ•์„ ์‚ฌ์šฉํ•˜์—ฌ HTML ์˜ˆ์ œ๋ฅผ ๋ณด๋„๋ก ํ•˜์ž.

<p>{% raw %}{{ ponies | slice:0:2 | json }}{% endraw %}</p>

์ด ์˜ˆ์ œ๋Š” ์กฐ๋ž‘๋ง ๋ชฉ๋ก์˜ ์ฒ˜์Œ ๋‘ ์š”์†Œ๋ฅผ ํ‘œ์‹œํ•œ๋‹ค. slice๋Š” ๋ฐฐ์—ด๊ณผ ๋ฌธ์ž์—ด๋กœ ์ž‘๋™ํ•˜๋ฏ€๋กœ ๋ฌธ์ž์—ด์„ ์ž๋ฅผ ์ˆ˜๋„ ์žˆ๋‹ค.

<p>{% raw %}{{ 'Ninja Squad' | slice:0:5 }}{% endraw %}</p>

'Ninja'๋งŒ ํ‘œ์‹œ๋  ๊ฒƒ์ด๋‹ค. ์Šฌ๋ผ์ด์Šค ํŒŒ์ดํ”„์— ํ•˜๋‚˜์˜ ์ธ๋ฑ์Šค n๋งŒ์„ ์ค„ ์ˆ˜ ์žˆ์œผ๋ฉฐ n์—์„œ ๋๊นŒ์ง€ ์š”์†Œ๋ฅผ ๊ฐ€์ ธ์˜ฌ๊ฒƒ์ด๋‹ค.

<p>{% raw %}{{ 'Ninja Squad' | slice:3 }}{% endraw %}</p>
<!-- will display 'ja Squad' -->

์Œ์ˆ˜๋ฅผ ์ง€์ •ํ•˜๋ฉด ๋’ค์—์„œ ๋ถ€ํ„ฐ ์ž๋ฅผ ๊ฒƒ์ด๋‹ค.

<p>{% raw %}{{ 'Ninja Squad' | slice:-5 }}{% endraw %}</p>
<!-- will display 'Squad' -->

์šฐ๋ฆฌ๊ฐ€ ๋ณด์•˜ ๋“ฏ์ด, ํŒŒ์ดํ”„์—๊ฒŒ ์ข…๋ฃŒ ์ธ๋ฑ์Šค๋ฅผ ์ค„ ์ˆ˜ ์žˆ๋‹ค :์ด ์ธ๋ฑ์Šค๊นŒ์ง€ ์š”์†Œ๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ์ด ์ธ๋ฑ์Šค๊ฐ€ ์Œ์ˆ˜์ด๋ฉด ์ธ๋ฑ์Šค๊นŒ์ง€ ์š”์†Œ๋ฅผ ์ทจํ•˜์ง€๋งŒ ๋์—์„œ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•œ๋‹ค.

<p>{% raw %}{{ 'Ninja Squad' | slice:2:-2 }}{% endraw %}</p>
<!-- will display 'nja Squ' -->

์ž„์˜์˜ ํ‘œํ˜„์‹์—์„œ slice๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ NgFor์—์„œ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

import { Component } from '@angular/core';
@Component({
  selector: 'ns-ponies',
  template: `<div *ngFor="let pony of ponies | slice:0:2">{% raw %}{{pony.name}}{% endraw %}</div>`
})
export class PoniesComponent {
  ponies: Array<any> = [
   { name: 'Rainbow Dash' },
   { name: 'Pinkie Pie' },
   { name: 'Fluttershy' }
  ];
}

์ด ๊ตฌ์„ฑ ์š”์†Œ๋Š” ์ปฌ๋ ‰์…˜์— ์Šฌ๋ผ์ด์Šค ํŒŒ์ดํ”„๋ฅผ ์ ์šฉ ํ–ˆ์œผ๋ฏ€๋กœ ์ฒซ ๋ฒˆ์งธ ๋‘ ์กฐ๋ž‘๋ง์— ๋Œ€ํ•ด ๋‘ ๊ฐœ์˜ div ์š”์†Œ๋ฅผ ๋งŒ๋“ ๋‹ค. ํŒŒ์ดํ”„ ์ธ์ˆ˜๋Š” ๋ฌผ๋ก  ๋™์  ๊ฐ’์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

import { Component } from '@angular/core';
@Component({
  selector: 'ns-ponies',
  template: `<div *ngFor="let pony of ponies | slice:0:size">{% raw %}{{pony.name}}{% endraw %}</div>`
})
export class PoniesComponent {
  size: number = 2;
  ponies: Array<any> = [
   { name: 'Rainbow Dash' },
   { name: 'Pinkie Pie' },
   { name: 'Fluttershy' }
  ];
}

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

์ด ํŒŒ์ดํ”„์˜ ์ด๋ฆ„์ด ์ถฉ๋ถ„ํžˆ ๋ช…ํ™• ํ•ด์ง€๋ฉด์„œ์ด ํŒŒ์ดํ”„๋Š” ๋ฌธ์ž์—ด์„ ๋Œ€๋ฌธ์ž๋กœ ๋ณ€ํ™˜ ํ•œ๋‹ค.

<p>{% raw %}{{ 'Ninja Squad' | uppercase }}{% endraw %}</p>
<!-- will display 'NINJA SQUAD' -->

์ด ํŒŒ์ดํ”„์˜ ์ด๋ฆ„์ด ์ถฉ๋ถ„ํžˆ ๋ช…ํ™• ํ•ด์ง€๋ฉด์„œ์ด ํŒŒ์ดํ”„๋Š” ๋ฌธ์ž์—ด์„ ์†Œ๋ฌธ์ž๋กœ ๋ณ€ํ™˜ ํ•œ๋‹ค.

<p>{% raw %}{{ 'Ninja Squad' | lowercase }}{% endraw %}</p>
<!-- will display 'ninja squad' -->

์ด ํŒŒ์ดํ”„๋Š” ์ˆซ์ž์˜ ์„œ์‹์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. {integerDigits} {minFractionDigits} - {maxFractionDigits} ํ˜•์‹์˜ ๋ฌธ์ž์—ด ํ•˜๋‚˜๊ฐ€ ํ•„์š”ํ•˜์ง€๋งŒ ๋ชจ๋“  ๋ถ€๋ถ„์€ ์„ ํƒ ์‚ฌํ•ญ ์ด๋‹ค. ๊ฐ ๋ถ€๋ถ„์€ ๋‹ค์Œ์„ ๋‚˜ํƒ€๋‚ธ๋‹ค. โ€ข ์ •์ˆ˜ ๋ถ€๋ถ„์— ์›ํ•˜๋Š” ์ˆ˜์˜ ๊ฐœ์ˆ˜ โ€ข ์†Œ์ˆ˜ ๋ถ€๋ถ„์—์„œ ์›ํ•˜๋Š” ์ˆซ์ž์˜ ์ˆ˜ โ€ข ์†Œ์ˆ˜ ๋ถ€๋ถ„์—์„œ ์›ํ•˜๋Š” ์ˆซ์ž์˜ ์ˆ˜ ํŒŒ์ดํ”„๊ฐ€ ์—†๋Š” ๊ฒƒ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๋Š” ๋ช‡ ๊ฐ€์ง€ ์˜ˆ์ด๋‹ค.

<p>{% raw %}{{ 12345 }}{% endraw %}</p>
<!-- will display '12345' -->

์ˆซ์ž ํŒŒ์ดํ”„๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ˆซ์ž๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ์—๋„ ์ •์ˆ˜ ๋ถ€๋ถ„์ด ๊ทธ๋ฃนํ™” ๋œ๋‹ค.

<p>{% raw %}{{ 12345 | number }}{% endraw %}</p>
<!-- will display '12,345' -->

integerDigits ๋งค๊ฐœ ๋ณ€์ˆ˜๋Š” ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์ •์ˆ˜ ๋ถ€๋ถ„์„ 0์œผ๋กœ ์™ผ์ชฝ์— ์ฑ„์›Œ ์ค€๋‹ค.

<p>{% raw %}{{ 12345 | number:'6.' }}{% endraw %}</p>
<!-- will display '012,345' -->

minFractionDigits๋Š” ์†Œ์ˆ˜ ๋ถ€๋ถ„์˜ ์ตœ์†Œ ํฌ๊ธฐ์ด๋ฏ€๋กœ ๋„๋‹ฌ ํ•  ๋•Œ๊นŒ์ง€ ์˜ค๋ฅธ์ชฝ์— 0์„ ์ฑ„์›Œ ์ค€๋‹ค.

<p>{% raw %}{{ 12345 | number:'.2' }}{% endraw %}</p>
<!-- will display '12,345.00' -->

maxFractionDigits๋Š” ์†Œ์ˆ˜ ๋ถ€๋ถ„์˜ ์ตœ๋Œ€ ํฌ๊ธฐ์ด๋‹ค. ๊ทธ๊ฒƒ์„ ์›ํ•œ๋‹ค๋ฉด minFractionDigits๋ฅผ 0์œผ๋กœ ์ง€์ •ํ•ด์•ผ ํ•œ๋‹ค. ์ˆซ์ž๊ฐ€ ๊ทธ ๋ณด๋‹ค ์†Œ์ˆ˜ ์ด์ƒ์ด๋ฉด ๋ฐ˜์˜ฌ๋ฆผ๋œ๋‹ค.

<p>{% raw %}{{ 12345.13 | number:'.1-1' }}{% endraw %}</p>
<!-- will display '12,345.1' -->
<p>{% raw %}{{ 12345.16 | number:'.1-1' }}{% endraw %}</p>
<!-- will display '12,345.2' -->

ํŒŒ์ดํ”„ (๋ฐฑ๋ถ„์œจ๊ณผ ํ†ตํ™”๋Š” ๋ฌผ๋ก )๋Š” ๋ธŒ๋ผ์šฐ์ €์˜ ๊ตญ์ œํ™” API๋ฅผ ์‚ฌ์šฉํ•˜๋ฉฐ ์ด API๋Š” ํ˜„์žฌ ๋ชจ๋“  ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค. ์ด๋Š” ์•Œ๋ ค์ง„ ๋ฌธ์ œ์ด๋ฉฐ ์ผ๋ถ€ ๋ธŒ๋ผ์šฐ์ € (Safari / iOS ๋“ฑ)์—์„œ์ด API์— ๋Œ€ํ•ด polyfill์„ ์‚ฌ์šฉํ•˜๋„๋ก ํ•ด์•ผ ํ•œ๋‹ค.

์ˆซ์ž์™€ ๋™์ผํ•œ ์›์น™์— ๋”ฐ๋ผ ๋ฐฑ๋ถ„์œจ์€ ๋ฐฑ๋ถ„์œจ์„ ํ‘œ์‹œ ํ•  ์ˆ˜ ์žˆ๋‹ค.

<p>{% raw %}{{ 0.8 | percent }}{% endraw %}</p>
<!-- will display '80%' -->
<p>{% raw %}{{ 0.8 | percent:'.3' }}{% endraw %}</p>
<!-- will display '80.000%' -->

์ƒ์ƒํ•  ์ˆ˜ ์žˆ๋“ฏ์ด ํŒŒ์ดํ”„๋Š” ์›ํ•˜๋Š” ํ†ตํ™”๋กœ ๊ธˆ์•ก์„ ํ˜•์‹ํ™” ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ ์–ด๋„ ํ•˜๋‚˜์˜ ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ์ง€์ •ํ•ด์•ผ ํ•œ๋‹ค.

โ€ข ํ†ตํ™”๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ISO ๋ฌธ์ž์—ด ( 'EUR', 'USD'...) โ€ข ์„ ํƒ์ ์œผ๋กœ ๊ธฐํ˜ธ ( 'โ‚ฌ', '$') ๋˜๋Š” ISO ๋ฌธ์ž์—ด์„ ์‚ฌ์šฉํ• ์ง€ ์—ฌ๋ถ€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋ถ€์šธ ํ”Œ๋ž˜๊ทธ. ๊ธฐ๋ณธ์ ์œผ๋กœ, ํ”Œ๋ž˜๊ทธ๋Š” false์ด๋ฉฐ ์‹ฌ๋ณผ์€ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค. โ€ข ์„ ํƒ์ ์œผ๋กœ number์™€ ๋™์ผํ•œ ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ธˆ์•ก์„ ํ˜•์‹ํ™”ํ•˜๋Š” ๋ฌธ์ž์—ด

<p>{% raw %}{{ 10.6 | currency:'EUR' }}{% endraw %}</p>
<!-- will display 'EUR10.60' -->
<p>{% raw %}{{ 10.6 | currency:'USD':true }}{% endraw %}</p>
<!-- will display '$10.60' -->
<p>{% raw %}{{ 10.6 | currency:'USD':true:'.3' }}{% endraw %}</p>
<!-- will display '$10.600' -->

๋‚ ์งœ ํŒŒ์ดํ”„๋Š” ๋‚ ์งœ ๊ฐ’์„ ์›ํ•˜๋Š” ํ˜•์‹์˜ ๋ฌธ์ž์—ด๋กœ ํฌ๋งท์ด๋‹ค. ๋‚ ์งœ๋Š” Date ๊ฐœ์ฒด ๋˜๋Š” ๋ฐ€๋ฆฌ ์ดˆ๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค. ์ง€์ •๋œ ํ˜•์‹์€ 'dd / MM / yyyy', 'MM-yy'๋˜๋Š” 'short', 'longDate'๋“ฑ๊ณผ ๊ฐ™์ด ๋ฏธ๋ฆฌ ์ •์˜ ๋œ ๊ธฐํ˜ธ ์ด๋ฆ„ ์ค‘ ํ•˜๋‚˜ ์ผ ์ˆ˜ ์žˆ๋‹ค.

<p>{% raw %}{{ birthday | date:'dd/MM/yyyy' }}{% endraw %}</p>
<!-- will display '16/07/1986' -->
<p>{% raw %}{{ birthday | date:'longDate' }}{% endraw %}</p>
<!-- will display 'July 16, 1986' -->

๋ฌผ๋ก  ๋‚ ์งœ์˜ ์‹œ๊ฐ„ ๋ถ€๋ถ„์„ ํ‘œ์‹œ ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

<p>{% raw %}{{ birthday | date:'HH:mm' }}{% endraw %}</p>
<!-- will display '15:30' -->
<p>{% raw %}{{ birthday | date:'shortTime' }}{% endraw %}</p>
<!-- will display '3:30 PM' -->

๋น„๋™๊ธฐ ํŒŒ์ดํ”„๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋น„๋™๊ธฐ ์ ์œผ๋กœ ๊ฐ€์ ธ์˜จ ๋ฐ์ดํ„ฐ๋ฅผ ํ‘œ์‹œ ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋‚ด๋ถ€์ ์œผ๋กœ ๋น„๋™๊ธฐ ๋ฐ์ดํ„ฐ๊ฐ€ Promise ๋˜๋Š” Observable์—์„œ ์˜จ ๊ฒƒ์ธ์ง€ ์—ฌ๋ถ€์— ๋”ฐ๋ผ PromisePipe ๋˜๋Š” ObservablePipe๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. Promise๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์ด์ œ๋Š” ์•Œ๊ณ  ์žˆ์–ด์•ผ ํ•œ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ES6 ์žฅ์œผ๋กœ ๋Œ์•„๊ฐ€์„œ Observable๋ฅผ ํ™•์ธํ•˜๋„๋ก ํ•˜๋ผ.

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

import { Component } from '@angular/core';
@Component({
  selector: 'ns-greeting',
  template: `<div>{% raw %}{{ asyncGreeting | async }}{% endraw %}</div>`
})
export class GreetingComponent {
  asyncGreeting = new Promise(resolve => {
   // after 1 second, the promise will resolve
   window.setTimeout(() => resolve('hello'), 1000);
  });
}

๋น„๋™๊ธฐ ํŒŒ์ดํ”„๊ฐ€ asyncGreeting ๋ณ€์ˆ˜์— ์ ์šฉ๋œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. 1์ดˆ ํ›„์— ๊ฐ’์ด ๋ฐ”์ธ๋”ฉ ๋˜๋ฉด ํŠธ๋ฆฌ๊ฑฐ๋ฅผ ํƒˆ ๊ฒƒ์ด๋‹ค.

<div>hello</div>

๋”์šฑ ํฅ๋ฏธ๋กœ์šด ๊ฒƒ์€ ์†Œ์Šค๊ฐ€ Observable ์ธ ๊ฒฝ์šฐ ์‚ฌ์šฉ์ž๊ฐ€ ๋‹ค๋ฅธ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ํƒ์ƒ‰ ํ•  ๋•Œ์™€ ๊ฐ™์ด ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ํŒŒ๊ดด ๋  ๋•Œ ํŒŒ์ดํ”„๊ฐ€ ๊ตฌ๋… ์ทจ์†Œ ๋ถ€๋ถ„ ์ž์ฒด๋ฅผ ์ฒ˜๋ฆฌํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

๋ฌผ๋ก  ํŒŒ์ดํ”„๋ฅผ ์ง์ ‘ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ๊ณ  ๋•Œ๋กœ๋Š” ๋งค์šฐ ์œ ์šฉํ•˜๋‹ค. AngularJS 1.x์—์„œ๋Š” ๋งž์ถค ํ•„ํ„ฐ๋ฅผ ์ž์ฃผ ์‚ฌ์šฉํ•˜์˜€๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์šฐ๋ฆฌ๋Š” ์šฐ๋ฆฌ์˜ ์• ํ”Œ ๋ฆฌ์ผ€์ด์…˜์˜ ๋ช‡ ๊ฐ€์ง€ (3 ์ผ ์ „ agoor 12์ดˆ ๋“ฑ) ์‚ฌ์šฉ์ž๊ฐ€ ํ•œ ์ž‘์—… ๊ฒฝ๊ณผ ์–ผ๋งˆ๋‚˜ ๋งŽ์€ ์‹œ๊ฐ„์„ ํ‘œ์‹œ ํ•˜๋‚˜๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค. Angular 2์—์„œ ์šฐ๋ฆฌ๊ฐ€ ์–ด๋–ป๊ฒŒ ํ•  ๊ฒƒ์ธ์ง€ ๋ณด์ž.

๋จผ์ € ์ƒˆ๋กœ์šด ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•˜๊ณ  ๊ทธ๊ฒƒ์€ PipeTransform ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค. ์ด ์ธํ„ฐํŽ˜์ด์Šค๋Š” ๋ฌด๊ฑฐ์šด ๋ฌผ๊ฑด์„ ๋“ค์—ฌ๋‹ค ๋ณด๋Š” transform () ๋ฉ”์†Œ๋“œ๋ฅผ ํ•„์š”๋กœ ํ•œ๋‹ค.

import { PipeTransform, Pipe } from '@angular/core';
export class FromNowPipe implements PipeTransform {
  transform(value, args) {
   // do something here
  }
}

Now ํ•จ์ˆ˜์˜ Moment.js๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‚ ์งœ ์ดํ›„ ์–ผ๋งˆ๋‚˜ ๋งŽ์€ ์‹œ๊ฐ„์ด ๊ฒฝ๊ณผํ–ˆ๋Š”์ง€ ํ‘œ์‹œํ•œ๋‹ค. ์›ํ•˜๋Š” ๊ฒฝ์šฐ NPM์„ ์‚ฌ์šฉํ•˜์—ฌ Moment.js๋ฅผ ์„ค์น˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

npm install moment

SystemJS ๊ตฌ์„ฑ์— ์ถ”๊ฐ€ํ•˜์—ฌ๋ผ.

map: {
  '@angular': 'node_modules/@angular',
  'rxjs': 'node_modules/rxjs',
  'moment': 'node_modules/moment/moment'
}

TypeScript๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์ธํ„ฐํŽ˜์ด์Šค๋„ ํ•„์š”ํ•˜๋‹ค.

typings install --save --ambient moment-node
import { PipeTransform, Pipe } from '@angular/core';
import * as moment from 'moment';
export class FromNowPipe implements PipeTransform {
  transform(value, args) {
   return moment(value).fromNow();
  }
}

์ด์ œ ์šฐ๋ฆฌ๋Š” ์•ฑ์— ํŒŒ์ดํ”„๋ฅผ ๋“ฑ๋กํ•ด์•ผ ํ•œ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด ์šฐ๋ฆฌ๊ฐ€ ์‚ฌ์šฉํ•  ์ˆ˜์žˆ๋Š” ํŠน๋ณ„ํ•œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๊ฐ€ ์žˆ๋‹ค : @Pipe

import { PipeTransform, Pipe } from '@angular/core';
import * as moment from 'moment';
@Pipe({ name: 'fromNow' })
export class FromNowPipe implements PipeTransform {
  transform(value, args) {
   return moment(value).fromNow();
  }
}

์„ ํƒํ•œ ์ด๋ฆ„์€ ํ…œํ”Œ๋ฆฟ์—์„œ ํŒŒ์ดํ”„๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜์žˆ๋Š” ์ด๋ฆ„์ด ๋œ๋‹ค. ํ…œํ”Œ๋ฆฟ์—์„œ ํŒŒ์ดํ”„๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋งˆ์ง€๋ง‰์œผ๋กœํ•ด์•ผ ํ•  ์ผ์€ @NgModule์˜ ์„ ์–ธ์— ํŒŒ์ดํ”„๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

@NgModule({
  imports: [BrowserModule],
  declarations: [PonyRacerAppComponent, RacesComponent, FromNowPipe],
  bootstrap: [PonyRacerAppComponent]
})
export class AppModule {
}

slice

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

์ธ์ˆ˜๋ฅผ ํŒŒ์ดํ”„์— ์ „๋‹ฌํ•˜๋ ค๋ฉด ์ฝœ๋ก  :์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜ ๋‹ค์Œ์— ์ฝœ๋ก  (:) ๋ฐ ๋‘ ๋ฒˆ์งธ ์ธ์ˆ˜ ๋“ฑ์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค.

Reference URL

Last updated