Angular: ์ œ์•ˆ: Observable๋กœ ์ž…๋ ฅ

์— ๋งŒ๋“  2015๋…„ 12์›” 08์ผ  ยท  183์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: angular/angular

์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค, ์ €๋Š” ์˜์–ด๋ฅผ ์ž˜ ๋ชปํ•ฉ๋‹ˆ๋‹ค.

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

๋ชฉํ‘œ

  • ๋ถ€๋ชจ์˜ ์ž…๋ ฅ ๋ฐ์ดํ„ฐ์™€ ์ž์‹์˜ ์ž…๋ ฅ ์†์„ฑ์ด ๋™๊ธฐํ™”๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ๊ฐœ๋ฐœ์ž๋Š” ์ž…๋ ฅ ์†์„ฑ์ด ๋น„๋™๊ธฐ์ ์œผ๋กœ ๋ณ€๊ฒฝ๋œ๋‹ค๋Š” ์ ์„ ์ดํ•ดํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

    ์ œ์•ˆ

@Component({ selector: "child" })
class Child {
  @Input("input") inputValue: Observable<T>;

  ngOnInit() {
    this.inputValue.map((value)=>...);
  }
}

@Component({
  template: `
  <child [input]="valueToChild"></child>
  `
})
class Parent {
  valueToChild: T;
}

์œ„์˜ ์ฝ”๋“œ๋Š” ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ Observable<T> ๋กœ ์ž…๋ ฅ์„ ๋ฐ›์œผ๋ ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์ž‘์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

@Component({ selector: "child" })
class Child {
  @Input("input") inputValue: Observable<T>
}

@Component({
  template: `
  <child [input]="valueToChild"></child>
  `
})
class Parent {
  valueToChild: Observable<T> = new Observable<T>((observer)=>{
    ...
    observer.next(val);
  });
}

์˜ˆ: http://plnkr.co/edit/BWziQygApOezTENdTVp1?p=preview

์ด๊ฒƒ์€ ์ž˜ ์ž‘๋™ํ•˜์ง€๋งŒ ํ•„์ˆ˜์ ์ธ ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ๋ถ€๋ชจ์˜ ์ž…๋ ฅ ๋ฐ์ดํ„ฐ๋Š” ์›๋ž˜ ๋‹จ์ˆœ ๋ฐ์ดํ„ฐ์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ด ์ œ์•ˆ์ด ์šฐ๋ฆฌ๋ฅผ ํ–‰๋ณตํ•˜๊ฒŒ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๊ฐ์‚ฌ ํ•ด์š”.

core inputs / outputs feature Needs Design

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

์นœ์• ํ•˜๋Š” Angular ํŒ€. 2020๋…„์—๋Š” ๋ฌด์—‡์ด๋“  ๊ธฐ๋Œ€ํ•ด์ฃผ์„ธ์š” :-)

๋˜ํ•œ @jcomputer ์†”๋ฃจ์…˜์€ ๋‚ด๊ฐ€ ์›ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์ด๋ฆ„์˜ ์—ด๋ ฌํ•œ ํŒฌ์€ ์•„๋‹ˆ์ง€๋งŒ @ViewChild ๊ฐ€ { read } ๊ฐ–๋Š” ๊ฒƒ๊ณผ ์œ ์‚ฌํ•œ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ:

@Input({ observable: true }) 
@Input({ asObservable: true }) 
@Input({ asSubject: true })

๋ชจ๋“  183 ๋Œ“๊ธ€

์•ˆ๋…•ํ•˜์„ธ์š” @laco0416 - ๋‹น์‹ ์˜ ์˜์–ด๋Š” ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค, ๊ฑฑ์ •ํ•˜์ง€ ๋งˆ์„ธ์š”!

์ €๋Š” ์ด ์•„์ด๋””์–ด๊ฐ€ ๋งค์šฐ ๋งˆ์Œ์— ๋“ญ๋‹ˆ๋‹ค. ์ด์ „์— ๋…ผ์˜ํ•œ ๋ฐ” ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ https://github.com/angular/angular/issues/4062 (๋ณด๊ธฐ ์ด๋ฒคํŠธ ๊ด€์ฐฐ) ๋ฐ https://github.com/angular/angular/issues/5467 (๋ถ€๋ชจ๋กœ๋ถ€ํ„ฐ ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ์ž์‹ ์ด๋ฒคํŠธ)๊ณผ๋„ ์ž˜ ๋งž์Šต๋‹ˆ๋‹ค.

๋ชจ๋“  ์‚ฌ๋žŒ์ด Observable์„ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์–ดํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋ฏ€๋กœ(์ด ์‚ฌ๋žŒ๋“ค์€ ๋†“์น˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค!) ๋‘ ์‚ฌ์šฉ ์‚ฌ๋ก€์— ๋Œ€ํ•œ ์˜ต์…˜์„ ์ œ๊ณตํ•ด์•ผ ํ•˜๋ฏ€๋กœ @Input() ๋ฅผ Observable๋กœ ์ง์ ‘ ๋งŒ๋“ค ๊ฐ€๋Šฅ์„ฑ์€ ๊ฑฐ์˜ ์—†์Šต๋‹ˆ๋‹ค. @ObserveInput() ๊ฐ™์€ ๊ฒƒ์ด ์žˆ์œผ๋ฉด ํšจ๊ณผ๊ฐ€ ์žˆ์„ ๊ฑฐ๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” _์ดํ›„_ ๋ฒ ํƒ€๋ฅผ ์ถœ์‹œํ•˜์—ฌ ์ œ ์ƒ๊ฐ์— ๋” ํฅ๋ฏธ๋กœ์šด ๊ธฐ๋Šฅ ์ค‘ ์ผ๋ถ€์— ๋Œ€ํ•ด ๋…ผ์˜ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ทธ ๋™์•ˆ์—๋Š” ์ด ์•„์ด๋””์–ด์˜ ๊ธฐ๋ณธ(๊ทธ๋ฆฌ๊ณ  _๋งค์šฐ_ ์‹คํ—˜์ !!! ์‹ค์ œ๋กœ ํ•˜์ง€ ๋งˆ์„ธ์š”) ๊ตฌํ˜„์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๋‹น์‹ ์ด ์ƒ๊ฐํ•˜๊ณ  ์žˆ๋˜ ๊ฐœ๋…์ ์ž…๋‹ˆ๊นŒ? http://plnkr.co/edit/Nvyd9IPBZp9OE2widOcW?p=preview

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

@alexpods ์ €๋Š” ์—ฌ๊ธฐ์— ์žˆ๋Š” ์•„์ด๋””์–ด๊ฐ€ ์ •ํ™•ํžˆ - ์ž…๋ ฅ ์†์„ฑ์˜ ๋ณ€๊ฒฝ์„ _๋“ฃ๋Š”__ ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•˜๊ณ , ๊ฐ’์„ ์—…์ŠคํŠธ๋ฆผ์œผ๋กœ ๋‚ด๋ณด๋‚ด์ง€ ์•Š๊ณ , ๋‚ด๊ฐ€ ์šฐ๋ คํ•˜๋Š” ํ•œ ์ ˆ๋Œ€์ ์œผ๋กœ ๊ดœ์ฐฎ์€ ๊ฒƒ์ด๋ผ๊ณ  ๋ฏฟ์Šต๋‹ˆ๋‹ค.

@robwormald

๋‹น์‹ ์˜ ์˜์–ด๋Š” ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค, ๊ฑฑ์ • ๋งˆ์„ธ์š”!

๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! ์ •๋ง ์•ˆ์‹ฌ์ด ๋ฉ๋‹ˆ๋‹ค.

๋‹น์‹ ์˜ @ObserveInput ๋Š” ๋‚ด๊ฐ€ ์›ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค!
๋˜ํ•œ @Input ์—๋Š” ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์—†์Šต๋‹ˆ๋‹ค. ์•„์ฃผ ์ข‹์€ ํ•ด๊ฒฐ์ฑ…์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

@alexpods ์ €๋„ ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค.

์ž…๋ ฅ ์†์„ฑ์˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ Observable๋กœ ์ˆ˜์‹  ๋Œ€๊ธฐํ•˜๊ณ  ๊ฐ’์„ ์—…์ŠคํŠธ๋ฆผ์œผ๋กœ ๋‚ด๋ณด๋‚ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” Rob๊ณผ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

@laco0416 ์•— , ์˜คํ•ดํ•ด์„œ ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. "์ž์‹ ๊ตฌ์„ฑ ์š”์†Œ์—์„œ ์ž…๋ ฅ ์†์„ฑ์ด ๋ณ€๊ฒฝ๋œ ๊ฒฝ์šฐ"๋ผ๋Š” ๋ฌธ๊ตฌ๊ฐ€ ๋‚˜๋ฅผ ํ˜ผ๋ž€์Šค๋Ÿฝ๊ฒŒ ํ–ˆ์Šต๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์— ๋Œ“๊ธ€์„ ๋‹ฌ์•„์•ผ ํ•˜๋Š”์ง€ ์•„๋‹ˆ๋ฉด ์ƒˆ ๋ฌธ์ œ๋ฅผ ์—ด์–ด์•ผ ํ•˜๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ž˜๋ชป๋œ ์œ„์น˜์— ์š”์ฒญ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒฝ์šฐ ์•Œ๋ ค์ฃผ์‹ญ์‹œ์˜ค.

๋‚˜๋Š” ๊ทธ๋Ÿฐ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์ž‘์„ฑํ•˜๋ ค๊ณ  ์‹œ๋„ํ–ˆ์ง€๋งŒ(์ง€๊ธˆ๊นŒ์ง€๋Š” ์‹คํŒจํ–ˆ์ง€๋งŒ) @robwormald ์˜ plunkr ์„ ์šฐ์—ฐํžˆ ๋ฐœ๊ฒฌํ–ˆ๋Š”๋ฐ _๊ฑฐ์˜_ ์™„๋ฒฝํ•˜๊ฒŒ(๊ทธ๋Ÿฌ๋‚˜ ์™„์ „ํžˆ๋Š” ์•„๋‹˜) ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

์ด ์ ‘๊ทผ ๋ฐฉ์‹์ด ์ €๋ฅผ ํฅ๋ถ„์‹œํ‚จ ๊ฒƒ์€ ngOnChanges ์ˆ˜๋ช… ์ฃผ๊ธฐ ํ›„ํฌ์— ํ™œ์šฉํ•˜๊ณ  ์žˆ๋‹ค๋Š” ์‚ฌ์‹ค์ด์—ˆ์Šต๋‹ˆ๋‹ค.
๋‚ด๊ฐ€ ๋ณด๊ณ  ์‹ถ์€ ๊ฒƒ์€ onChanges$: Observable<{[key: string]: SimpleChange}> , onInit$: Observable<{}> ๋“ฑ๊ณผ ๊ฐ™์ด _all_ ์ˆ˜๋ช… ์ฃผ๊ธฐ ํ›„ํฌ๊ฐ€ Observable๋กœ ๋…ธ์ถœ๋˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

๋ชจ๋“  ์ˆ˜๋ช… ์ฃผ๊ธฐ ํ›„ํฌ๋ฅผ Observable๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋ฉด ๋ชจ๋“  ๊ฒƒ์„ Rxํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค ;-)

์ด์— ๋Œ€ํ•œ ์—…๋ฐ์ดํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

AFAIK, ์•„๋‹ˆ.
@robwormald ์†Œ์‹์ด ์žˆ๋‚˜์š”?

๋‚˜๋Š” ์ด๊ฒƒ์ด ์˜ค๋ž˜๋˜์—ˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์ง€๋งŒ ์ด๊ฒƒ์€ ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค! @robwormald ์ด๊ฒƒ์— ๋Œ€ํ•ด

@robwormald ์˜ @ObserveInput ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๊ฐ€ ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ @Input ์†์„ฑ ๊ฐ’์„ Observable๋กœ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์„ ์ œ๊ณตํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ ๊ธฐ์กด(Angular 1) ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์„ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•  ๋•Œ ๋ถ€๋ชจ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ Observable์„ ์ „๋‹ฌํ•˜๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด ํ•ญ์ƒ ๊ฐ€๋Šฅํ•œ ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‹จ์ผ ๊ตฌ์„ฑ ์š”์†Œ ๋‚ด์— Observable์„ "ํฌํ•จ"ํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์€ RxJS์˜ ๊ฐ•๋ ฅํ•จ๊ณผ ์šฐ์•„ํ•จ์„ ํ™œ์šฉํ•˜๋Š” ๊ฒƒ์„ ํ›จ์”ฌ ์–ด๋ ต๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

๋ถˆํ–‰ํžˆ๋„ Rob์€ ์ด ๋ฒ„์ „์˜ @ObserveInput ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ๋ง๋ผ๊ณ  ๋งํ•œ ๊ฒƒ์€ ๋†๋‹ด์ด ์•„๋‹™๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ๊ฒช๊ณ  ์žˆ๋Š” ๋ฌธ์ œ๋Š” Observable์ด "ํด๋ž˜์Šค ์ˆ˜์ค€"(ํ•ด๋‹น ์šฉ์–ด๊ฐ€ ์˜๋ฏธ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ)์—์„œ ์ƒ์„ฑ๋˜์–ด ๊ตฌ์„ฑ ์š”์†Œ์˜ ๋ชจ๋“  ์ธ์Šคํ„ด์Šค์—์„œ ๊ณต์œ ๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋ถ„๋ช…ํžˆ ์ข‹์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ธ์Šคํ„ด์Šคํ™” ์‹œ๊ฐ„์— Observable์„ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ๋„ ์ €์—๊ฒŒ ํšจ๊ณผ๊ฐ€ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. Angular๊ฐ€ ์ด ๊ฒฝ์šฐ ๋ณ€๊ฒฝ ๊ฐ์ง€๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์—ฐ๊ฒฐํ•˜์ง€ ์•Š๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

@ObserveInput ์˜ ๋” ๋‚˜์€ ๊ตฌํ˜„์„ ๊ด€๋ฆฌํ•œ ์‚ฌ๋žŒ์ด ์žˆ์Šต๋‹ˆ๊นŒ? ์•„๋‹ˆ๋ฉด ๊ณต์‹ ์ง€์›์— ๋Œ€ํ•œ ์†Œ์‹์ด ์žˆ์Šต๋‹ˆ๊นŒ?

@lephyrus ๊ณต์‹ @ObserveInput ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” ๋งค์šฐ ํ›Œ๋ฅญํ•˜์ง€๋งŒ @Input ์†์„ฑ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋Š” Observable์„ ์–ป๊ธฐ ์œ„ํ•ด ๊ผญ ํ•„์š”ํ•œ ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” ๋‹จ์ˆœํžˆ ๋งค์šฐ ์šฐ์•„ํ•œ "์„คํƒ•"์ž…๋‹ˆ๋‹ค.

์ด๋ฏธ ์ˆ˜๋ช… ์ฃผ๊ธฐ ์ด๋ฒคํŠธ ngOnChanges ์žˆ์Šต๋‹ˆ๋‹ค. ngOnChanges ๋‚ด๋ถ€์—์„œ rxjs Subject ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๊ด€์ฐฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ:

<strong i="13">@Input</strong> inputString: string;
private Subject<string> inputString$ = new Subject<string>;

ngOnChanges(changes: { [key: string]: SimpleChange }) {
    if (changes.hasOwnProperty('inputString')) {
        this.inputString$.next(changes['inputString'].currentValue);
    }
}

constructor() {
    inputString$.subscribe(x => {
        console.log('inputString is now', x);
    });
}

๋˜๋Š” ๋” ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๊ฒƒ์„ ์›ํ•˜๋ฉด ๊ตฌ์„ฑ ์š”์†Œ extends ๊ธฐ๋ณธ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

import { SimpleChange } from '@angular/core';
import { Observable, ConnectableObservable, Observer } from 'rxjs';

export interface TypedSimpleChange<T> {
    previousValue: T;
    currentValue: T;
}

export class ReactiveComponent {
    private changesObserver: Observer<{ [key: string]: SimpleChange }>;
    private changes$: ConnectableObservable<{ [key: string]: SimpleChange }>;

    constructor() {
        this.changes$ = Observable.create((observer: Observer<{ [key: string]: SimpleChange }>) => this.changesObserver = observer).publishReplay(1);
        this.changes$.connect();
    }

    public observeProperty<T>(propertyName: string): Observable<TypedSimpleChange<T>> {
        return this.changes$
            .filter(changes => changes.hasOwnProperty(propertyName))
            .map(changes => changes[propertyName]);
    }

    public observePropertyCurrentValue<T>(propertyName: string): Observable<T> {
        return this.observeProperty<T>(propertyName)
            .map(change => change.currentValue);
    }

    ngOnChanges(changes: { [key: string]: SimpleChange }) {
        this.changesObserver.next(changes);
    }
}

... ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@Component({
    ...
})
export class YourComponent extends ReactiveComponent {
    @Input() inputString: string;

    constructor() {
        super();
        this.observePropertyCurrentValue<string>('inputString')
            .subscribe(x => console.log('inputString is now', x));
    }
}

๊ณต์‹ @ObserveInput ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์„ ๋•Œ๊นŒ์ง€ ์ด ์ ‘๊ทผ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

@wmaurer๋‹˜, ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๊ท€ํ•˜์˜ ReactiveComponent ๋Š” ๋งค์šฐ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค. ํ ์žก์„ ๋ฐ ์—†๋Š” ์ฝ”๋“œ์™€ ์•ˆ์ „ํ•œ ํƒ€์ดํ•‘์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ถ€ํŒ…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ •๋ง ์ข‹์Šต๋‹ˆ๋‹ค! ์ค‘์š”ํ•œ ๊ฒƒ์€ ํ…Œ์ŠคํŠธ์—์„œ๋„ ์ž˜ ์ž‘๋™ํ•˜๋ฉฐ OnPush ๋ณ€๊ฒฝ ๊ฐ์ง€ ์ „๋žต์„ ๊ณ„์† ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด์ œ "๊ณต์‹ ์„คํƒ•"์„ ๊ธฐ๋‹ค๋ฆฌ๊ฒŒ ๋˜์–ด ๊ธฐ์ฉ๋‹ˆ๋‹ค. (๋˜ํ•œ Observable.create() ๋…ผ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ์ด์œ ๋ฅผ ์•Œ๊ฒŒ ๋˜๋ฉด ๋ญ”๊ฐ€๋ฅผ ๋ฐฐ์šฐ๊ฒŒ ๋  ๊ฒƒ์ด๋ผ๊ณ  ํ™•์‹ ํ•ฉ๋‹ˆ๋‹ค. ์•„์ง ์‚ดํŽด๋ณผ ์‹œ๊ฐ„์ด ์—†์Šต๋‹ˆ๋‹ค.) ๋‹ค์‹œ: merci gรคll! :๋ˆˆ์ง“:

@lephyrus ์ฒœ๋งŒ ์—์š”, gรคrn gescheh ;-)

๋‚ด๊ฐ€ ์‚ฌ์šฉ Observable.create() ์žก์•„ ์–ป์„ Observer ํ•  ์ˆ˜ ์žˆ๋„๋กํ•˜๊ธฐ ์œ„ํ•ด next() . ๋‚ด๊ฐ€ ์‚ฌ์šฉํ–ˆ์„ ์ˆ˜์žˆ๋Š” Subject ์ธ์„ ๋‘˜ ๋ชจ๋‘ Observable ์™€ Observer , ๊ทธ๋Ÿฌ๋‚˜ ๋‚˜๋Š” ๊ทธ๊ฒƒ์ด '๋…ธ์ถœ'์— ์ผ๋ฐ˜์ ์œผ๋กœ ๋‚˜์œ ๊ด€ํ–‰ ๋ฏฟ์Šต๋‹ˆ๋‹ค Subject ( Observer ).

@laco0416 ์€ https://github.com/angular/angular/issues/13248 ์— ์ฐฌ์„ฑํ•˜์—ฌ ๋งˆ๊ฐํ•ฉ๋‹ˆ๊นŒ?

@DzmitryShylovich ์•„๋‹ˆ์š”.

@ObserveInput ์ •๋ง ๋ฉ‹์งˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค! :+1:

์ข‹์€ ์˜ˆ๋ฅผ ๋ณด์—ฌ์ฃผ์‹  @wmaurer๋‹˜ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ํ•œ ๊ฐ€์ง€ ์งˆ๋ฌธ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ด€์ฐฐ ๊ฐ€๋Šฅ ๊ฐœ์ฒด๋กœ ๋ฌธ์ž์—ด ๋Œ€์‹  ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ์›ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ

@Input() chartConfig: ChartConfig;

constructor(private _reportService: ReportService) {
        super();
             this.observePropertyCurrentValue<string>('chartConfig')
            .subscribe(changedConfig => this.updateChart(changedConfig));
 }

export class ChartConfig {
    public id: string;
    public type: any;
    public data: any;
    public labels: any;
}

๊ทธ๋Ÿฌ๋‚˜ this.updateChart ๋ฐ ngOnChanges๋Š” ํ˜ธ์ถœ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋Œ€์‹ ์— ๊ฐœ์ฒด๋ฅผ ๊ด€์ฐฐํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ„๋‹จํ•œ ๋ฌธ์ž์—ด์—์„œ ์ƒ˜ํ”Œ์„ ํ™•์žฅํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

@ChrisWorks ๊ฐ์ฒด์—์„œ๋„ ์ž‘๋™ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

this.observePropertyCurrentValue<ChartConfig>('chartConfig')
            .subscribe(changedConfig => console.log(changedConfig));

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

์•ˆ๋…•ํ•˜์„ธ์š” @wmaurer๋‹˜ , ๋‹ต๋ณ€ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. "config" ๊ฐœ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ž‘์—… ๋ฒ„์ „์œผ๋กœ ์ƒ˜ํ”Œ์„ ํ™•์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ๋‚˜๋Š” ๋‹จ์ˆœํžˆ ๋‚ด ์ผ์„ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ƒ˜ํ”Œ Git ๋ฆฌํฌ์ง€ํ† ๋ฆฌ? :)

@ChrisWorks ์ •๋ง ์žˆ๋Š” ๊ทธ๋Œ€๋กœ ์ž‘๋™ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. observePropertyCurrentValue ๋Š” ๋ฌธ์ž์—ด ์ž…๋ ฅ๊ณผ ๊ฐœ์ฒด๋ฅผ ๊ตฌ๋ถ„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
๋‹ค์Œ์€ ์ž…๋ ฅ์ด ๋ฌธ์ž์—ด๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋ชจ๋“  ๋‹ค๋ฅธ ์œ ํ˜•์ธ ๊ณณ์—์„œ ๋งŒ๋“  ์ •๋ง ์˜ค๋ž˜๋œ ng2 ๋ฒ ํƒ€ 0 ํ”„๋กœ์ ํŠธ์ž…๋‹ˆ๋‹ค.
https://github.com/wmaurer/todomvc-ng2-reactive
์˜ˆ: https://github.com/wmaurer/todomvc-ng2-reactive/blob/master/src/app/todo-item/todo-item.component.ts

+1 ์ด๋Ÿฌํ•œ ๊ธฐ๋ณธ์ ์ธ ์‚ฌ์šฉ ์‚ฌ๋ก€๋Š” ์•„์ง ์ •๋ ฌ๋˜์ง€ ์•Š์•˜๋‹ค๋Š” ๊ฒƒ์ด ๋ฏฟ๊ธฐ์ง€ ์•Š์Šต๋‹ˆ๋‹ค!

๋งˆ์นจ๋‚ด ์ตœ๊ณ ์˜ ์†”๋ฃจ์…˜์„ ์–ป์—ˆ๊ณ  AOT ์ปดํŒŒ์ผ๊ณผ ํ•จ๊ป˜ ๋ฐ˜๋ณต ์—†์ด ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๋น„๋ฐ€์€ @Input() ๋ฅผ ๋‘ ๋ฒˆ์งธ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์™€ ๊ฒฐํ•ฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ฐ์ฝ”๋ ˆ์ดํ„ฐ:

import { ReplaySubject } from 'rxjs/ReplaySubject'                                                                                                 

const subjects = new WeakMap()                                                                                                                     

export function ObservableInput() {                                                                                                
  return (target, propertyKey) => {                                                                                                                
    delete target[propertyKey]                                                                                                                     

    Object.defineProperty(target, propertyKey, {                                                                                                   
      set(value) {                                                                                                                                 
        this[propertyKey].next(value)                                                                                                              
      },                                                                                                                                                                                                                            
      get() {                                                                                                                                      
        let subject = subjects.get(this)                                                                                                           
        if (! subject)  {                                                                                                                          
          subject = new ReplaySubject<any>(1)                                                                                                      
          subjects.set(this, subject)                                                                                                              
        }                                                                                                                                          
        return subject                                                                                                                             
      },                                                                                                                                           
    })                                                                                                                                             
  }                                                                                                                                                
}                                                                                                                                                  

์šฉ๋ฒ•:

class SomeComponent {
  @Input() @ObservableInput()                                                                                                                    
  public index: Observable<number>
}                                                                                                               

ํŽธ์ง‘: ์ด์ œ ์ด๊ฒƒ์„ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ๊ฐœ์„ ํ•  ์•„์ด๋””์–ด๋ฅผ ๋ฐ›๊ฒŒ ๋˜์–ด ๊ธฐ์ฉ๋‹ˆ๋‹ค. ๊ธฐ์กด @Input ๋ฅผ Observable ๋ณด์™„ํ•˜๋Š” ์ƒˆ๋กœ์šด ๋ฐฉ๋ฒ•์„ ๋‹ค์Œ์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. https://github.com/ohjames/observable-input ์ฐธ์กฐ

๊ทธ๋Ÿฐ ์ผ์„ ํ•ด์•ผ ํ•œ๋‹ค๋ฉด ์ฐจ๋ผ๋ฆฌ ngOnChanges: Subject<SimpleChanges> ์— ๋Œ€ํ•œ ๋‹จ์ผ ์ฃผ์ œ ์•„๋‚ ๋กœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.
์›ํ•˜๋Š” ๊ฒฝ์šฐ ์—ฌ์ „ํžˆ ํ•˜๋‚˜์˜ ํŠน์ • ์ž…๋ ฅ์—๋งŒ ํ•„ํ„ฐ๋ง ๋ฐ ๋งคํ•‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

1 ์ž…๋ ฅ๋‹น ์ฃผ์ œ๋Š” getter ๋ฐ setter๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ํด๋ž˜์Šค ์†Œํ’ˆ์„ ์‚ญ์ œํ•˜๊ณ  ์ž…๋ ฅ ์œ ํ˜•์ด ์ž˜๋ชป๋˜์—ˆ์œผ๋ฉฐ input = value ํ•˜๋ฉด ์‹ค์ œ๋กœ ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ๊ฐ’์„ ๋‚ด๋ณด๋‚ด๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•˜์ง€ ์•Š๊ณ  ๋งŽ์ด ๋ณด์ž…๋‹ˆ๋‹ค. ๋‹น์‹ ์˜ ์ฃผ์ œ๋ฅผ ์™„๋ฃŒํ•ฉ๋‹ˆ๋‹ค.

์—ฌ๊ธฐ ์—์„œ ๋‚ด ์•„์ด๋””์–ด์˜ ๊ตฌํ˜„ ์˜ˆ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์ ‘๊ทผ ๋ฐฉ์‹์€ ์‹คํ—˜์  ์ด์ง€๋งŒ ์ƒ์† ์ ‘๊ทผ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋งค์šฐ ์•ˆ์ „ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค(์—ฌ๊ธฐ์— ํ‘œ์‹œํ•˜๊ธฐ ์œ„ํ•ด ์ง€๊ธˆ ์ˆ˜ํ–‰ํ–ˆ์œผ๋ฉฐ ์‚ฌ์šฉ๋˜์ง€ ์•Š์Œ).

@ghetolay ์ฃผ์ œ๊ฐ€ ์™„๋ฃŒ๋˜์—ˆ๋Š”์ง€ ์—ฌ๋ถ€๋Š” ์ค‘์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ณด๊ธฐ๊ฐ€ ๋‹ซํžˆ๋ฉด ์ŠคํŠธ๋ฆผ์— ๋Œ€ํ•œ ๊ตฌ๋…์ด ๋” ์ด์ƒ ์—†๊ณ  GC์—์„œ

changes$ ๋Š” ๊ตฌ์„ฑ ์š”์†Œ์— ๋Œ€ํ•œ BehaviorSubject ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋ˆ„์ถœํ•ฉ๋‹ˆ๋‹ค. ์ด์ƒ์ ์œผ๋กœ๋Š” Observable<...> ๋กœ ์ž…๋ ฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋งŽ์€ ์ฃผ์ œ์˜ ๋ฌธ์ œ์— ๊ด€ํ•ด์„œ๋Š”... n ์ฃผ์ œ๋ฅผ ์‚ฌ์šฉํ•˜๋“  1 ๋ฅผ ์‚ฌ์šฉํ•˜๋“  ์—ฌ์ „ํžˆ n ๊ตฌ๋…์ด ์žˆ์Šต๋‹ˆ๋‹ค. 1๊ฐœ์˜ ์ฃผ์ œ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ๊ฐ ๊ตฌ๋…์— ํ•˜๋‚˜์˜ ๋งต ์—ฐ์‚ฐ์ž์™€ ํ•˜๋‚˜์˜ ํ•„ํ„ฐ ์—ฐ์‚ฐ์ž๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฒŒ ๋˜๋ฉด, ์ด๊ฒƒ์˜ ์„ฑ๋Šฅ ์˜ค๋ฒ„ํ—ค๋“œ๋Š” n ์ฃผ์ œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ํ›จ์”ฌ ์ž‘์ง€ ์•Š์„ ๊ฒƒ์ด๋ฉฐ ๋” ๋‚˜์  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ž…๋ ฅ ๋งค๊ฐœ๋ณ€์ˆ˜ ์ž์ฒด์˜ ํƒ€์ดํ•‘์„ ๋ฌด์‹œํ•˜๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ๊ธฐ๋ฐ˜ ๋ฒ„์ „์€ any ๊ธฐ๋ฐ˜์˜ SimpleChange ์œ ํ˜•๋ณด๋‹ค ์˜ต์ €๋ฒ„๋ธ” ์†Œ๋น„์ž์—๊ฒŒ ๋” ์œ ํ˜•์ด ์•ˆ์ „ํ•œ API๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

@ohjames

๋ณด๊ธฐ๊ฐ€ ๋‹ซํžˆ๋ฉด ์ŠคํŠธ๋ฆผ์— ๋Œ€ํ•œ ๊ตฌ๋…์ด ๋” ์ด์ƒ ์—†๊ณ  GC์—์„œ ์‚ญ์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ชจ๋“  ๊ตฌ๋…์ด ๋ณด๊ธฐ์— ์—ฐ๊ฒฐ๋˜๊ณ  ๋ณด๊ธฐ์™€ ๋™์ผํ•œ ์ˆ˜๋ช… ์ฃผ๊ธฐ๋ฅผ ๊ฐ–๊ฒŒ ๋œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค. Observable์ด ์–ด๋–ป๊ฒŒ ์†Œ๋น„๋˜๋Š”์ง€์— ๋Œ€ํ•ด ์–ด๋–ค ๊ฐ€์ •๋„ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์˜ต์ €๋ฒ„๋ธ”์—์„œ ๊ฐ’์„ ๋‚ด๋ณด๋‚ด๋Š” ๊ฒƒ์ด ๊ธฐ๋ณธ์ ์œผ๋กœ ์ด๊ฒƒ์˜ ์š”์ ์ž…๋‹ˆ๋‹ค. Angular ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ํ˜„์žฌ ์ž…๋ ฅ ์†์„ฑ ์œ ํ˜•์„ ํ™•์ธํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋” ๊ณต์‹์ ์ธ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ๋•Œ์ฏค์ด๋ฉด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ;)

๋‚˜๋Š” ์‚ฌ์šฉ์ž๋ฅผ ์œ„ํ•ด ์‚ฌ์šฉ์ž๊ฐ€ ์—ฌ์ „ํžˆ ์†์„ฑ์— ์•ก์„ธ์Šคํ•˜๊ณ  ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Œ์„ ์˜๋ฏธํ–ˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ Observable๋กœ ์ž…๋ ฅ๋œ ๊ฒƒ์„ ์ œ์™ธํ•˜๊ณ ๋Š” ์†์„ฑ์„ ์ˆซ์ž์ธ ๊ฒƒ์ฒ˜๋Ÿผ ์„ค์ •ํ•˜๊ณ  ์†์„ฑ์„ ์„ค์ •ํ•˜์ง€ ์•Š๊ณ  ๋ฐฉ์ถœํ•˜๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋‚˜์—๊ฒŒ ๋งค์šฐ ํ˜ผ๋ž€ ์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค.

๋งŽ์€ ์ฃผ์ œ์˜ ๋ฌธ์ œ์— ๊ด€ํ•ด์„œ๋Š”... n๊ฐœ์˜ ์ฃผ์ œ๋ฅผ ์‚ฌ์šฉํ•˜๋“  1๊ฐœ์˜ ์ฃผ์ œ๋ฅผ ์‚ฌ์šฉํ•˜๋“  ์—ฌ์ „ํžˆ n๊ฐœ์˜ ๊ตฌ๋…์ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜๋‚˜์˜ ์ฃผ์ œ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ๊ฐ ๊ตฌ๋…์— ํ•˜๋‚˜์˜ ๋งต ์—ฐ์‚ฐ์ž์™€ ํ•˜๋‚˜์˜ ํ•„ํ„ฐ ์—ฐ์‚ฐ์ž๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฒŒ ๋˜๋ฉฐ, ์ด๊ฒƒ์˜ ์„ฑ๋Šฅ ์˜ค๋ฒ„ํ—ค๋“œ๋Š” n๊ฐœ์˜ ์ฃผ์ œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ํ›จ์”ฌ ์ž‘์ง€ ์•Š์œผ๋ฉฐ ๋” ๋‚˜์  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” ๊ณง ์ฃผ์š” ๋ชฉ์ ์— ๋Œ€ํ•œ ์ดˆ์ ์„ ์žƒ์„ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ์—ฌ๊ธฐ์„œ ์ด๋Ÿฐ ์ข…๋ฅ˜์˜ ํ† ๋ก ์— ๋“ค์–ด๊ฐ€์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Subject ๋…ธ์ถœํ•˜์ง€ ์•Š๋„๋ก ์—…๋ฐ์ดํŠธํ–ˆ๊ณ  ๋ณ€๊ฒฝ ์‚ฌํ•ญ์— ํƒ€์ดํ•‘์„ ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•ด ๋ฌด์–ธ๊ฐ€๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.
๋‚˜๋Š” BehaviorSubject ์•„๋‹ˆ๋ผ ํ‰๋ฒ”ํ•œ Subject ์™œ๋ƒํ•˜๋ฉด Observable์„ ๊ฐ€์น˜ ๋ณด์œ ์ž๋กœ ๋ณด์ง€ ์•Š๊ณ  ์‹œ๊ฐ„์ด ์ง€๋‚จ์— ๋”ฐ๋ผ ๋ณ€ํ™”ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
๋ฐฉ๊ธˆ ๊ฒฐํ•จ์„ ์ฐพ์•˜์Šต๋‹ˆ๋‹ค. ๋น„๋™๊ธฐ ํŒŒ์ดํ”„๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๋น„๋™๊ธฐ ํŒŒ์ดํ”„๊ฐ€ ์ฒซ ๋ฒˆ์งธ ๋ฐฉ์ถœ ํ›„์— ๊ตฌ๋…ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ฒซ ๋ฒˆ์งธ ๊ฐ’์ด ๋ฐฉ์ถœ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ๋ฅผ ์ ์ ˆํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ๋‚˜์ค‘์— ์ฝ”๋“œ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์—ฌ๊ธฐ ๋‹ค์‹œ ๋งํฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค: https://stackblitz.com/edit/angular-observableinput?file=observablechanges%2Fimpl.ts

๋ชจ๋“  ๊ตฌ๋…์ด ๋ณด๊ธฐ์— ์—ฐ๊ฒฐ๋˜๊ณ  ๋ณด๊ธฐ์™€ ๋™์ผํ•œ ์ˆ˜๋ช… ์ฃผ๊ธฐ๋ฅผ ๊ฐ–๊ฒŒ ๋œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค. Observable์ด ์–ด๋–ป๊ฒŒ ์†Œ๋น„๋˜๋Š”์ง€์— ๋Œ€ํ•ด ์–ด๋–ค ๊ฐ€์ •๋„ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋„ค ์š”์ ์„ ์•Œ๊ฒ ์Šต๋‹ˆ๋‹ค. Observable์„ ์™„๋ฃŒํ•˜๋ฉด ๋ชจ๋“  ๊ตฌ๋…์ด ๊ฐ•์ œ ์ข…๋ฃŒ๋˜์ง€๋งŒ ์‹ค์ œ๋กœ ๊ฑฑ์ •ํ•  ์ •๋„๋Š” ์•„๋‹™๋‹ˆ๋‹ค. ์šฐ๋ฆฌ ์•ฑ์—์„œ ๊ตฌ๋…์˜ 99%๋Š” ๋น„๋™๊ธฐ ํŒŒ์ดํ”„๋ฅผ ํ†ตํ•ด ๋ฐœ์ƒํ•˜๋ฉฐ, ์ข…์ข… CombineLatest/switchMap์„ ํ†ตํ•ด Redux/etc์—์„œ ์ œ๊ณต๋˜๋Š” ์™ธ๋ถ€ ๊ด€์ฐฐ ๊ฐ€๋Šฅ ํ•ญ๋ชฉ์„ ์†Œ์Šค๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์–ด์จŒ๋“  ์ˆ˜๋™์œผ๋กœ ๋‹ซ์„ ํ•„์š”๊ฐ€ ์—†๋Š” ์†Œ์ˆ˜์˜ ๊ตฌ๋…์ž…๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” ๊ณง ์ฃผ์š” ๋ชฉ์ ์— ๋Œ€ํ•œ ์ดˆ์ ์„ ์žƒ์„ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ์—ฌ๊ธฐ์„œ ์ด๋Ÿฐ ์ข…๋ฅ˜์˜ ํ† ๋ก ์— ๋“ค์–ด๊ฐ€์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ธ€์Ž„์š” ๋‹น์‹ ์€ ์ž˜๋ชป๋œ ๋น„ํŒ์„ ์ œ๊ธฐํ–ˆ์œผ๋ฏ€๋กœ ๊ทธ๊ฒƒ์— ๋Œ€์‘ํ•  ํ•„์š”๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

~๋˜ํ•œ ์ƒ์†์„ ํ†ตํ•ด ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. AOT ์ปดํŒŒ์ผ๋Ÿฌ์— ์˜ํ•ด ์ƒ์„ฑ๋œ ์ฝ”๋“œ๋Š” ์ƒ์œ„ ํด๋ž˜์Šค์—์„œ ์ˆ˜๋ช… ์ฃผ๊ธฐ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. https://github.com/angular/angular/issues/12756#issuecomment -260804139๋ฅผ ์ฐธ์กฐ ngOnDestroy() { super.ngOnDestroy() } ๋ฐ ngOnChanges ์— ๋Œ€ํ•œ ๋˜ ํ•˜๋‚˜๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ~ <-- Angular 4.4์—์„œ ํŠน์ • ์ œํ•œ ์‚ฌํ•ญ์œผ๋กœ ์ˆ˜์ •๋œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

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

๊ทธ๋ž˜์„œ ๋‚ด ์ด์ „ ์ง„์ˆ ์ด ๊ดœ์ฐฎ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

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

์ด ์ฝ”๋“œ๋Š” ๊ณ ๋„๋กœ ์‹คํ—˜์ ์ด๋ฉฐ ์ผ์ข…์˜ poc์ผ ๋ฟ์ด๋ฉฐ ํ•ด๋‹น stackblitz์—์„œ๋งŒ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.
๊ทธ๋ž˜์„œ ๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ๊ฝค ์•ˆ์ „ ํ•˜๋‹ค๊ณ  ๋งํ•˜์ง€ ๋ง์•˜์–ด์•ผ ํ–ˆ๊ณ  ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ง์”€ ํ•˜์‹  ๋Œ€๋กœ AOT์—์„œ ์ž‘๋™ํ•˜์ง€ ์•Š์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
๋ฐฉ๊ธˆ ์‹œ๋„ํ–ˆ๊ณ  ๋‘ ๊ฐ€์ง€ ์ ‘๊ทผ ๋ฐฉ์‹ ๋ชจ๋‘ ํ˜„์žฌ AOT(๊ฐ๋„ v4.3.6, cli v1.4.1)์—์„œ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์„œ ๋‚ด ์š”์ ์€ ๋ชจ๋“  ์ž…๋ ฅ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ํฌํ•จํ•˜๋Š” changes ๊ด€์ฐฐ ๊ฐ€๋Šฅ์—์„œ ์ด๋™ํ•˜๋ฉด ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•„์š”ํ•œ ๋ชจ๋“  ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ณ€๊ฒฝ, ํŠน์ • ๊ฐ’์—์„œ ๋‹ค๋ฅธ ๊ฐ’ ๋“ฑ์œผ๋กœ ๋ณ€๊ฒฝ๋˜์—ˆ์„ ๋•Œ...
์›ํ•˜๋Š” Observable์„ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ ๊ตฌํ˜„์„ ์œ„ํ•ด ๊ด€๋ฆฌํ•  ์ฃผ์ œ๋Š” 1๊ฐœ์ด๊ณ  ์‚ฌ์šฉ์ž๋ฅผ ์œ„ํ•ด ์‚ฌ์šฉํ•  ์†์„ฑ์€ ์ž…๋ ฅ๋‹น 1๊ฐœ๋ฟ์ž…๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์€ ์‚ฌ์šฉ์ž๊ฐ€ pair ๋ฐ map ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ SimpleChange ์™€ ๊ฐ™์€ ์ข…๋ฅ˜์˜ ๊ตฌ์กฐ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ SimpleChanges ๊ฐœ์ฒด๊ฐ€ ์•„๋‹Œ ์ƒˆ ๊ฐ’์„ ๋‚ด๋ณด๋‚ด๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. SimpleChange . ๊ทธ๋Ÿฌ๋‚˜ ํ˜„์žฌ ์šฐ๋ฆฌ๊ฐ€ ์–ป์€ ๊ฒƒ์€ SimpleChanges ์ด๋ฏ€๋กœ ๋‚˜์ค‘์— ๋น„์Šทํ•œ ๊ฒƒ์„ ์žฌ๊ตฌ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ๋ถ„ํ•ดํ•˜๋Š” ๊ฒƒ์€ ์–ด๋ฆฌ์„์€ ์ผ์ž…๋‹ˆ๋‹ค.

์ถ”์‹ :

๊ธ€์Ž„์š” ๋‹น์‹ ์€ ์ž˜๋ชป๋œ ๋น„ํŒ์„ ์ œ๊ธฐํ–ˆ์œผ๋ฏ€๋กœ ๊ทธ๊ฒƒ์— ๋Œ€์‘ํ•  ํ•„์š”๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

๋‹น์‹ ์—๊ฒŒ ์œ ํšจํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค .

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

๋งŽ์€ ์ž…๋ ฅ์— ๋ฐ˜์‘ํ•˜๋Š” ๊ฒฝ์šฐ... switchMap ๋˜๋Š” CombineLatest ๋˜๋Š” ์—ฌ๋Ÿฌ ๊ด€์ฐฐ ๊ฐ€๋Šฅ ํ•ญ๋ชฉ๊ณผ ํ•จ๊ป˜ ์ž‘๋™ํ•˜๋„๋ก ์„ค๊ณ„๋œ ๋‹ค๋ฅธ ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹น์‹ ์€ ์ด๊ฒƒ์— ๋Œ€ํ•ด ๋งค์šฐ ๋Œ€๋‹ดํ•˜๊ณ  ํฌ๊ด„์ ์ธ ๋ฐœ์–ธ์„ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ •๋ง๋กœ ์ด ๋Œ€ํ™”๋ฅผ ๊ณ„์†ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ์ด ์ด์Šˆ ํŠธ๋ž˜์ปค์—์„œ ์‚ญ์ œํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ์€ ๋‹ค์–‘ํ•œ ๋‹จ์ ๊ณผ ์žฅ์ ์ด ์žˆ์ง€๋งŒ ๊ธฐ๋ณธ ํด๋ž˜์Šค๊ฐ€ ํ•„์š”ํ•œ ๋ฒ„์ „์ž…๋‹ˆ๋‹ค.

import { OnChanges, OnDestroy, SimpleChanges } from '@angular/core'
import { BehaviorSubject } from 'rxjs/BehaviorSubject'
import { Observable } from 'rxjs/Observable'
import 'rxjs/add/operator/map'
import 'rxjs/add/operator/distinctUntilChanged'

export class ChangeObserver implements OnChanges, OnDestroy {
  protected ngChanges = new BehaviorSubject<object>({})

  ngOnChanges(changes: SimpleChanges) {
    const props = { ...this.ngChanges.value }
    for (const propName in changes) {
      props[propName] = changes[propName].currentValue
    }
    this.ngChanges.next(props)
  }

  ngOnDestroy() {
    this.ngChanges.complete()
  }

  changes<K extends keyof this>(key: K): Observable<this[K]>
  changes<V>(key: string): Observable<V>
  changes(key: string) {
    return this.ngChanges.map(props => this.ngChanges.value[key]).distinctUntilChanged()
  }
}

์‚ฌ์šฉํ•˜๋ ค๋ฉด:

class MyComponent extends ChangeObserver {
  @Input() public field: string
  // typescript knows this is Observable<string>
  field$ = this.changes('field')

  @Input() private privField: number
  // typescript can't access private stuff from outside the class so we need to help it out
  privField$ = this.changes<number>('privField')
}

๋‚ด๊ฐ€ ๋ฌธ์ œ๋ฅผ ์ž˜๋ชป ์ดํ•ดํ–ˆ๋Š”์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์ง€๋งŒ ๋น„๋™๊ธฐ ํŒŒ์ดํ”„๊ฐ€ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๊นŒ?
[inputVar]="observableValue | async" ..

@najibla ๋‹น์‹ ์ด ์ž˜๋ชป ์ดํ•ดํ–ˆ์Šต๋‹ˆ๋‹ค. ์ž…๋ ฅ์€ ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ๋น„๋™๊ธฐ ํŒŒ์ดํ”„๊ฐ€ ๋„์›€์ด๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

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

@najibla ์ด github ๋ฌธ์ œ๋Š” @Input ์†์„ฑ์„ ๊ด€์ฐฐ ๊ฐ€๋Šฅ ํ•ญ๋ชฉ์œผ๋กœ ๋ฐ”๊พธ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์„ค๋ช…ํ•˜๋Š” ๊ฒฝ์šฐ์™€ ๊ฑฐ์˜ ๊ด€๋ จ์ด ์—†์Šต๋‹ˆ๋‹ค.

์ฆ‰, ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ๊ด€์ฐฐ ๊ฐ€๋Šฅ ํ•ญ๋ชฉ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ณ€๊ฒฝ๋˜๋Š” ์ž…๋ ฅ ์†์„ฑ์— ์‘๋‹ตํ•˜๋Š”์ง€ ์—ฌ๋ถ€๋Š” ๊ตฌ์„ฑ ์š”์†Œ ์ž์ฒด์—์„œ ๊ฒฉ๋ฆฌ๋˜์–ด์•ผ ํ•˜๋ฏ€๋กœ ์ž…๋ ฅ ์†์„ฑ์„ ๋ณด๊ธฐ์—์„œ ๊ด€์ฐฐ ๊ฐ€๋Šฅ ํ•ญ๋ชฉ์œผ๋กœ ๋ณ€ํ™˜ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด Angular์˜ ์ผ๋ฐ˜์ ์ธ "๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ์šฐ์„ " ์ ‘๊ทผ ๋ฐฉ์‹๊ณผ ์ƒ๋ฐ˜๋˜๋Š” ์†์„ฑ์„ ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ๊ฒƒ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ•œ ๊ฒฝ์šฐ ๊ตฌ์„ฑ ์š”์†Œ์˜ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋ณ€๊ฒฝํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

@icepeng ์‹ค์ œ๋กœ ๋‹น์‹ ์€ ๊ทธ๊ฒƒ์„ ์ œ๋Œ€๋กœ ์ดํ•ดํ•˜์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ํ‘œ์ค€ ์ž…๋ ฅ์„ ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ๊ฒƒ์œผ๋กœ ๋ฐ”๊พธ๋Š” ๊ฒƒ์— ๊ด€ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ƒˆ ํŒจํ„ด์€ ์‹ค์ œ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

<app-child [prop]="prop$ | async"></app-child>

... ๊ทธ๋Ÿฐ ๋‹ค์Œ prop ๋‚ด๋ถ€์˜ AppChildComponent ์— Observable์ด ์•„๋‹ˆ๋”๋ผ๋„ Observable๋กœ ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ). ์ด์ œ ๋ฌผ๋ก  ์˜ˆ์—์„œ์™€ ๊ฐ™์ด ์ฒ˜์Œ์— prop$ ๊ฐ€ ์žˆ์—ˆ๋‹ค๋ฉด ํ•ฉ๋ฆฌ์ ์ด์ง€ ์•Š์€ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์ง€๊ธˆ ์ž…๋ ฅ์œผ๋กœ ๊ด€์ฐฐ ๊ฐ€๋Šฅ ํ•ญ๋ชฉ์„ ์ด๋ฏธ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Œ). ์ „๋‹ฌ ๋œ ์ž…๋ ฅ์ด ์ด๋ฏธ ๊ด€์ฐฐ ์•„๋‹Œ ๊ฒฝ์šฐ์—๋Š” ๊ทธ ๊ฐ’์„ ๋งŽ์ด ์ œ๊ณตํ•œ๋‹ค (์˜ˆ index ์—์„œ ngFor ).

์˜ต์ €๋ฒ„๋ธ”์„ ์ž…๋ ฅ์œผ๋กœ ์ „๋‹ฌํ•˜๋Š” ๋ฌธ์ œ(์ง€๊ธˆ์€ ์™„์ „ํžˆ ๊ฐ€๋Šฅํ•จ)๋Š” OnPush ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ฒƒ์„ ์ž˜ @fxck ๋‹น์‹  ๋งž์•„์š” ngOnChanges ํ˜ธ์ถœ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค ๋•Œ ๊ด€์ฐฐ ๋ฐฉ์ถœํ•œ๋‹ค (์ž…๋ ฅ์ด ๋™์ผํ•˜๊ฒŒ ์œ ์ง€ํ•˜๊ธฐ ๋•Œ๋ฌธ์—), ๊ทธ๋Ÿฌ๋‚˜๋งŒํผ ๋‹น์‹ ์ด ๋น„๋™๊ธฐ ํŒŒ์ดํ”„๋ฅผ ์‚ฌ์šฉ์œผ๋กœ ํ†ต๊ณผ ๊ด€์ธก์— ๊ฐ€์ž… @Input ๋‹ค์Œ OnPush ๋Š” ๋น„๋™๊ธฐ ํŒŒ์ดํ”„๊ฐ€ ์ž์‹ ๊ตฌ์„ฑ ์š”์†Œ์˜ ๋ณ€๊ฒฝ ๊ฐ์ง€๊ธฐ๋ฅผ ์ˆ˜๋™์œผ๋กœ ํŠธ๋ฆฌ๊ฑฐํ•˜๋ฏ€๋กœ ์ œ๋Œ€๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ, @icepeng์œผ๋กœ ํ–ฅํ–ˆ์Šต๋‹ˆ๋‹ค.

@ohjames @fxck ์˜ต์ €๋ฒ„ ๋ธ”์„ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์ด ์ง€๊ธˆ ๊ฐ€๋Šฅํ•œ์ง€ ๋ชฐ๋ž์Šต๋‹ˆ๋‹ค. ์ž˜๋ชป๋œ ์ •๋ณด๋ฅผ ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค.

Observable์„ ์ง์ ‘ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— @ObserveInput ๊ฐ€ ์œ ์šฉํ• ์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.
๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ’์ด Observable์ด ์•„๋‹ˆ๋ฉด ์ด๋ฏธ ๋ฌธ์ œ๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.
๊ฐœ์ธ์ ์ธ ์˜๊ฒฌ์ผ ๋ฟ์ž…๋‹ˆ๋‹ค.

@icepeng ์ด๊ฒƒ์„ ๊ณ ๋ คํ•˜์‹ญ์‹œ์˜ค:

<ng-container *ngFor="value in (values$ | async); let i = index">
  <child-component [value]="value" [index]="i"></child-component>
</ng-container>

index ๋ฅผ ํ›„ํ”„๋ฅผ ๊ฑด๋„ˆ ๋›ฐ์ง€ ์•Š๊ณ  ์—ฌ๊ธฐ์—์„œ ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

๋˜๋Š” ํƒ€์‚ฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ž‘์„ฑ ์ค‘์ด๊ณ  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์†Œ๋น„์ž๊ฐ€ ๊ตฌ์„ฑ ์š”์†Œ์— ๊ด€์ฐฐ ๊ฐ€๋Šฅ ํ•ญ๋ชฉ์„ ์ „๋‹ฌํ•˜๋„๋ก ๊ฐ•์ œํ•˜๊ณ  ์‹ถ์ง€ ์•Š๋‹ค๊ณ  ์ƒ๊ฐํ•ด ๋ณด์‹ญ์‹œ์˜ค(๋งŽ์€ ์‚ฌ์šฉ์ž๊ฐ€ ์ŠคํŠธ๋ฆผ์— ์ต์ˆ™ํ•˜์ง€ ์•Š๊ณ  rxjs๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Œ).

์ด๊ฒƒ์ด ์œ ์šฉํ•œ ๋‹ค๋ฅธ ๋งŽ์€ ๊ฒฝ์šฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

@ohjames index ๋Š” child-component ๊ฐ

BehaviorSubject ์ ‘๊ทผ ๋ฐฉ์‹์ด ๋” ๋‚˜์€ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. Angular ์ฝ”์–ด๊ฐ€ ์ด์™€ ๊ฐ™์€ @NgChanges() ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์ œ๊ณตํ•˜๋ฉด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

{
  @NgChanges() ngChanges$: BehaviorSubject<{ prop: string }>
  @Input() prop: string;

  ngOnInit() {
    this.ngChanges$.subscribe(changes => console.log(changes.prop));
  }
}

์ด๊ฒƒ์ด ๊ตฌํ˜„ ๊ฐ€๋Šฅํ•œ๊ฐ€์š”?

๋ฒ„ํผ ๊ธธ์ด๊ฐ€ 1์ธ ReplayObservable์ด ์„ ํ˜ธ๋˜๋ฉฐ ์†์„ฑ์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ BehaviourSubject์˜ ๊ฐ’ ์˜๋ฏธ ์ฒด๊ณ„๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๊ตฌํ˜„์ด ๊ฐ€๋Šฅํ•œ์ง€ ์—ฌ๋ถ€๋Š” ๋‹ค์–‘ํ•œ ๊ตฌํ˜„ ๋ฐ ์˜ต์…˜์— ๋Œ€ํ•œ ๋ฌธ์ œ ๋‚ด์—ญ์„ ํ™•์ธํ•˜์„ธ์š”. ์–ด๋Š ๊ฒƒ๋„ ํ›Œ๋ฅญํ•˜์ง€ ์•Š๊ณ  ์ผ๋ถ€๋Š” ์™„์ „ํžˆ ๋ง๊ฐ€์กŒ์Šต๋‹ˆ๋‹ค. ์ œ๋Œ€๋กœ ํ•˜๋ ค๋ฉด ์—ฐ๊ฒฐ๋œ PR ๋˜๋Š” ์ด์™€ ์œ ์‚ฌํ•œ ๊ฒƒ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

๋‚ด 2 ์„ผํŠธ: object.observe๊ฐ€ ํ”„๋ก์‹œ๋ฅผ ์„ ํ˜ธํ•˜์—ฌ ํ‰๊ฐ€์ ˆํ•˜๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋‚ด ์†”๋ฃจ์…˜์€ ํ”„๋ก์‹œ๋ฅผ ํ™•์žฅํ•œ ๋‹ค์Œ(์˜ˆ, ์•Œ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ƒ์„ฑ์ž์—์„œ ๋ฐ˜ํ™˜ํ•œ ์ด์œ ) ์—ฌ๊ธฐ์— ์†ํ•œ ํ‚ค๋ฅผ ์ˆ˜์‹ ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. $get(keyName) ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ๊ฐœ์ฒด๋ฅผ Observable๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. Angular ํด๋ž˜์Šค 1๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋ชจ๋“  ๊ฐ์ฒด์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';

/**
 * Extends this class to be able to observe any key affectation
 */
class ObservableProxy {
    private changes: Subject<[PropertyKey, any]> = new Subject<[PropertyKey, any]>();

    constructor() {
        return new Proxy(this, {
            set: (object, key, value) => {
                this.changes.next([key, value]);
                object[key] = value;
                return true;
            }
        });
    }

    public $get<K extends keyof this>(key: K): Observable<this[K]> {
        const value: this[K] = this[key];

        const startWith: Observable<this[K]> = Observable.of(value)
            .filter((initialValue) => // remove this filter if you dont mind receiving an undefined value on subscription
                initialValue !== undefined;
            );

        return this.changes
            .filter(([changedKey]) => {
                return changedKey === key;
            })
            .map(([changedKey, nextValue]) => nextValue)
            .merge(startWith);
    }
}

์˜ˆ์‹œ:

class User extends ObservableProxy {
public name: string;
}

const user: User = new User();
user.$get("name").subscribe((value)=> {
console.log(value);
})

user.name = "toto"; // prints console.log("toto")

@robwormald , ์ด ๋ฌธ์ œ์— ๋Œ€ํ•œ ๊ด€์‹ฌ์ด ์žˆ์Šต๋‹ˆ๊นŒ? ํ™•์‹คํžˆ ์‚ฌ์šฉํ•˜๊ธฐ ์‰ฝ๊ฒŒ ๋งŒ๋“œ๋Š” ๋ฐ ํฐ ๋„์›€์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@bryanrideshark ์ด๊ฒƒ์ด ์ง€์›๋  ๊ฐ€์žฅ ์ข‹์€ ๊ธฐํšŒ๋Š” https://github.com/angular/angular/issues/10185๋ฅผ ํ†ตํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ œ ์ƒ๊ฐ์—๋Š” PR์ด ์ด ๋ฌธ์ œ์™€ ์—ฐ๊ฒฐ๋˜์ง€ ์•Š์€ ๊ฒƒ์— ๋†€๋ž์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ์šฐ๋ฆฌ๊ฐ€ Ivy๋ฅผ ๋ฐฐ์†กํ•  ๋•Œ๊นŒ์ง€ ์ผ์–ด๋‚˜์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค
2018๋…„ 2์›” 21์ผ ์ˆ˜์š”์ผ ์˜ค์ „ 7์‹œ 56๋ถ„์— James Pike [email protected]์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ผ์Šต๋‹ˆ๋‹ค.

@bryanrideshark https://github.com/bryanrideshark ์ตœ๊ณ ์˜ ๊ธฐํšŒ
์ด๊ฒƒ์€ #10185๋ฅผ ํ†ตํ•ด ์ง€์›๋ฉ๋‹ˆ๋‹ค.
https://github.com/angular/angular/issues/10185 ์ œ ์ƒ๊ฐ์—๋Š” ๋†€๋ž์Šต๋‹ˆ๋‹ค.
PR์€ ์ด ๋ฌธ์ œ์™€ ๊ด€๋ จ์ด ์—†์Šต๋‹ˆ๋‹ค.

โ€”
๋‹น์‹ ์ด ์–ธ๊ธ‰๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์„ ๋ฐ›๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ด ์ด๋ฉ”์ผ์— ์ง์ ‘ ๋‹ต์žฅํ•˜๊ณ  GitHub์—์„œ ํ™•์ธํ•˜์„ธ์š”.
https://github.com/angular/angular/issues/5689#issuecomment-367372931 ,
๋˜๋Š” ์Šค๋ ˆ๋“œ ์Œ์†Œ๊ฑฐ
https://github.com/notifications/unsubscribe-auth/AAgpkvtGA4w8uHgiz0QsdYwBgqgM2EpAks5tXDyWgaJpZM4Gwr8f
.

๋‹น์‹ ์˜ ์˜์–ด๋Š” ํ›Œ๋ฅญํ•˜๊ณ  ๋‹น์‹ ์˜ ๊ฐ๋„๋Š” ๋” ํฝ๋‹ˆ๋‹ค.

@pldin601 ๊ท€ํ•˜์˜ ๋ฐฉ๋ฒ•์€ AOT ์ปดํŒŒ์ผ๋œ ์ฝ”๋“œ๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ๋žŒ๋“ค์˜ ํ”„๋กœ๋•์…˜ ์ฝ”๋“œ์— ๋Œ€ํ•ด ๋ง‰๋Œ€ํ•œ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๋Œ€์‹  AOT์™€ ์ž˜ ์ž‘๋™ํ•˜๋Š” observable-input ํŒจํ‚ค์ง€๋ฅผ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.

@pldin601 ์ฝ”๋“œ์˜ ๋ฌธ์ œ๋Š” ngOnDestroy ์ˆ˜๋ช… ์ฃผ๊ธฐ ๋ฉ”์„œ๋“œ๋ฅผ ๋™์ ์œผ๋กœ ์ถ”๊ฐ€ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. AOT ์ปดํŒŒ์ผ๋œ ์ฝ”๋“œ๋Š” ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๊ทธ ์กด์žฌ๋ฅผ ์ •์ ์œผ๋กœ ์ถ”๋ก ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ์—๋งŒ ngOnDestroy ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“  ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ngOnDestory ๋„ ์ •์˜ํ•˜๋Š” ๊ฒฝ์šฐ์—๋งŒ ๋ฉ”์„œ๋“œ๊ฐ€ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค(ํ•„์š”ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ๋น„์–ด ์žˆ์„ ์ˆ˜ ์žˆ์Œ). ๋‹ค๋ฅธ ๋ชจ๋“  ๊ฒฝ์šฐ์—๋Š” ๊ตฌ๋…์ด ๋ˆ„์ถœ๋˜์–ด ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ๊ฐ€๋น„์ง€ ์ˆ˜์ง‘๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.

์„น์…˜ 3.2๊ฐ€ ์™„๋ฃŒ๋œ ํ›„์— ์ผ์–ด๋‚  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๊นŒ(์ด ํ•„์š”์„ฑ์ด ๊ณ ๋ ค๋˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค)?
https://is-angular-ivy-ready.firebaseapp.com/#/status

Ivy๊ฐ€ 7.0.0์— ํฌํ•จ๋  ์˜ˆ์ •์ž…๋‹ˆ๊นŒ?

์†์„ฑ์„ ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ๋™๋ฐ˜์ž ์†์„ฑ์— ๋ฐ”์ธ๋”ฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ฐ๋„ ์ž…๋ ฅ ์†์„ฑ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋‹ค๋ฅธ ์†์„ฑ์—๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. @ohjames ์˜ @ObservableInput() ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์—์„œ ์˜๊ฐ์„ ์–ป์—ˆ์ง€๋งŒ Observable์„ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค๋ฅธ ์†์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ์†์„ฑ getter์™€ setter ๊ฐ„์˜ ์œ ํ˜• ๋ถˆ์ผ์น˜๋กœ ์ธํ•ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ๋ฅผ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.

https://github.com/PSanetra/bind-observable

์˜ˆ์‹œ:

class MyClass {

  @BindObservable()
  public myProp: string = 'initialValue';
  public myProp$!: Observable<string>;

}

const myInstance = new MyClass();

myInstance.myProp$.subscribe(console.log);

myInstance.myProp = 'newValue'

์ด ์ฝ”๋“œ๋Š” 'initialValue' ๋ฐ 'newValue' ์„ ์ฝ˜์†”์— ์ธ์‡„ํ•ฉ๋‹ˆ๋‹ค.

observable-input ํŒจํ‚ค์ง€๊ฐ€ ์ง€๊ธˆ๊นŒ์ง€ ์ถœ์‹œ๋  ์‹œ๊ธฐ์— ๋Œ€ํ•œ ์—…๋ฐ์ดํŠธ๋Š” ์•„๋ฌด ๊ฒƒ๋„ ๊นจ์ง€ ์•Š๊ณ  ํ•˜์œ„ ๋ถ„๋ฅ˜ ์—†์ด ๊ฐ€์žฅ ์šฐ์•„ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค. @ohjames ์ด ์‹œ์ ์—์„œ ์–ผ๋งˆ๋‚˜ ์•ˆ์ •์ ์ด๊ณ  ์ž˜ ํ…Œ์ŠคํŠธ๋˜์—ˆ์Šต๋‹ˆ๊นŒ?

๊ณต์‹ ์ง€์›์ด ๋” ์„ฑ์ˆ™ํ•ด์ง€๊ณ  ๋ฒ„์ „ ์ „๋ฐ˜์— ๊ฑธ์ณ ์ง€์†์ ์ธ ์ง€์›์ด ๋ณด์žฅ๋˜๊ณ  ๋” ๋ถ€๋“œ๋Ÿฌ์šด ๊ฐœ๋ฐœ ๊ฒฝํ—˜์ด ๋ณด์žฅ๋  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค./๊ฐœ๋ฐœ์ž๊ฐ€ ์ „์ฒด rxjs*๋กœ ์ „ํ™˜ํ•˜๊ณ  ํ‘ธ์‹œ ๋ณ€๊ฒฝ ๊ฐ์ง€๋กœ ์ตœ์ ํ™”ํ•˜๋„๋ก ์žฅ๋ คํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค(๋‚ด ์ƒ๊ฐ์— ํ•ต์‹ฌ์ ์ธ ํš๊ธฐ์ ์ธ ๊ธฐ๋Šฅ์ด์–ด์•ผ ํ•จ)

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

aot๊ฐ€ ์žˆ๊ฑฐ๋‚˜ ์—†๋Š” ๊ฐ๋„ 4, 5 ๋ฐ 7์—์„œ ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ์ž…๋ ฅ์„ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. ์ž˜ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ์ผ์„ ๋•Œ ๋‚ด๊ฐ€ ๋ฌด์—‡์„ ํ•˜๊ณ  ์žˆ์—ˆ๋Š”์ง€ ๋ง‰์—ฐํ•˜๊ฒŒ ์•Œ๊ณ  ์žˆ์—ˆ๋‹ค๊ณ  ํ™•์‹ ํ•œ๋‹ค.

ํ”„๋ ˆ์ž„์›Œํฌ์— ์ถ”๊ฐ€ํ•˜๊ณ  ์‚ฌ์šฉ์„ ๊ถŒ์žฅํ•˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. 2์ฃผ๊ฐ„ ๋‹ค์šด๋กœ๋“œ npm์€ ์ถ”๊ฐ€ํ•˜๋ฉด xD๊ฐ€ ์ œ๊ณตํ•˜๋Š” ์ด์ ์— ๋น„ํ•ด ์ถฉ๋ถ„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์‚ฌ๋žŒ๋“ค์ด ๊ทธ ์ ‘๊ทผ ๋ฐฉ์‹์„ ๋”ฐ๋ฅด๋Š” ๊ฒƒ์ด ๊ฐ„๋‹จํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์‚ฌ์šฉ์ž ์ •์˜ observer ๋น„๋™๊ธฐ ์ž…๋ ฅ์— ๋Œ€ํ•ด ๋‹ค์Œ API๋ฅผ ์ œ์•ˆํ•ฉ๋‹ˆ๋‹ค.

decalre function AsyncInput(bindName?:string) : <T extends Observer>(target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<T>) => any

์‚ฌ์šฉ์ž๋Š” ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@AsyncInput()
asynchronusProperty1 = new Subject();

@AsyncInput()
asynchronusProperty2 = new ReplySubject(1);

@AsyncInput()
asynchronusProperty3 = new UserObserver(); // where UserObserver implement `Observer` interface

Angular ๋‚ด๋ถ€๋Š” ๊ฐ’์ด ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค observer.next(newValue) ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@HostBinding ์ง€์›๋„ ์žŠ์ง€ ๋งˆ์„ธ์š”!

์ด๊ฒƒ์€ ์ƒ์„ฑ์ž @Input ์ฃผ์ž…๊ณผ ๊ฒฐํ•ฉํ•˜์—ฌ ํ›จ์”ฌ ๋” ๋ฉ‹์ง€๊ฒŒ ๋งŒ๋“ค์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋งค์šฐ ์šฐ์•„ํ•œ ๋ฐฉ์‹์œผ๋กœ "strictPropertyInitialization"์„ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

class MyComponent {
  inputData$: Observable<Data>;
  constant: string;

  constructor(
    @Input() inputData$: Observable<Data>,
    @Input() constantString: string
  ) {
    this.inputData$ = inputData$;
    this.constant = constantString;
  }

}

@benneq ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์— ์ฃผ๋ชฉํ•  ๊ฐ€์น˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

class MyComponent {
  constructor(
    @Input() private inputData$: Observable<Data>,
    @Input() private constantString: string,
  ) {}
}

@maxime1992 ๋„ค, ๊ด€์ฐฐ ๊ฐ€๋Šฅ ํ•ญ๋ชฉ์ด ํ•œ ๊ตฌ์„ฑ ์š”์†Œ์—์„œ ๋‹ค๋ฅธ ๊ตฌ์„ฑ ์š”์†Œ๋กœ ์ „๋‹ฌ๋˜๋Š” ๊ฒฝ์šฐ๋ฅผ ๊ตฌ๋ถ„ํ•˜๋ ค๋ฉด ์ž…๋ ฅ ํ•ญ๋ชฉ์— ๋Œ€ํ•ด ๋ณ„๋„์˜ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

@benneq @maxime1992 ๋งค๊ฐœ๋ณ€์ˆ˜ ์ด๋ฆ„์€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ์˜ ์ผ๋ถ€๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. ์–ด๋–ป๊ฒŒ ๋งคํ•‘ํ•˜๋‚˜์š”?

@trotyl ๊ทธ๋Ÿฌ๋ฉด @Input('paramName') private myParam: Observable<Data> ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

@trotyl @benneq ๋„ค, ์ œ ์ž˜๋ชป์ž…๋‹ˆ๋‹ค. ์‹ ๊ฒฝ์“ฐ์ง€ ๋งˆ์„ธ์š” :zipper_mouth_face:

๋ˆ„๊ตฐ๊ฐ€ ์ด๋ฏธ ์ด ์†”๋ฃจ์…˜์„ ๊ฒŒ์‹œํ–ˆ๋Š”์ง€๋Š” ๋ชจ๋ฅด๊ฒ ์ง€๋งŒ ์ด๊ฒƒ์€ ์ƒ๋‹นํžˆ ์ข‹์€ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

@ElianCordoba ์ด๊ฒƒ์€ HTML <input> ์— ๊ด€ํ•œ ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. ๊ฐ @Input()

๊ทธ๊ฒƒ์€ ๋‹ค๋ฅด์ง€๋งŒ ๋น„์Šทํ•˜๊ฒŒ ๊ณ ํ†ต์Šค๋Ÿฌ์šด ๋ฌธ์ œ @ElianCordoba์ž…๋‹ˆ๋‹ค. https://github.com/angular/angular/issues/13248

๋‚˜๋Š” ์ด๊ฒƒ์ด ์˜์‚ฌ ์š”๊ตฌ ์‚ฌํ•ญ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ฒซ์งธ, ์ž…๋ ฅ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” Observable ์œ ํ˜• ๊ฐ’์„ ๋ฐ›์•„๋“ค์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‘˜์งธ, ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์ž…๋ ฅ์œผ๋กœ ๊ด€์ฐฐ ๊ฐ€๋Šฅ์„ ์š”๊ตฌํ•˜๋Š” ๊ฒฝ์šฐ ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•˜์ง€ ์•Š์€ ๊ฐ’์„ ์ˆ˜์‹ ํ•  ๋•Œ ์กฐ์šฉํžˆ Observable ์œ ํ˜• ๊ฐ’์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๋Œ€์‹  ๋ช…์‹œ์ ์œผ๋กœ ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒ์‹œ์ผœ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ์•”์‹œ์  ์œ ํ˜• ๋ณ€ํ™˜๊ณผ ๋งค์šฐ ์œ ์‚ฌํ•˜์—ฌ ๋ฒ„๊ทธ๋ฅผ ์œ ๋ฐœํ•˜๊ณ  ์ฐพ๊ธฐ ์–ด๋ ค์šธ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

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

๋ฐ˜๋Œ€๋กœ ์˜ต์ €๋ฒ„๋ธ”์„ ์š”๊ตฌํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋…ธ์ถœํ•˜๋Š” ๊ฒƒ์€ ํˆฌ๋ฐ•ํ•˜๊ฒŒ ๋“ค๋ฆด ๋ฟ ์•„๋‹ˆ๋ผ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ๊ทธ๋ ‡๊ฒŒ ์ด์ƒํ•˜๊ฒŒ ๋“ค๋ฆฐ๋‹ค๋Š” ์ด์œ ๋งŒ์œผ๋กœ ์‚ฌ๋žŒ๋“ค์ด of(value)๋ฅผ ์ œ๊ณตํ•˜๋„๋ก ๊ฐ•์š”ํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ ์ž๋™ ๋ณ€ํ™˜์ด ์•„๋‹ˆ๋ผ rxjs๋ฅผ ํ†ตํ•ด ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๊ตฌ๋…ํ•˜๋Š” API์ž…๋‹ˆ๋‹ค. angular.http์™€ ๋ผ์šฐํ„ฐ๊ฐ€ ์˜ต์ €๋ฒ„๋ธ”์„ ์ œ๊ณตํ•˜๋Š” ๊ฒฝ์šฐ ์ž…๋ ฅ ๋ณ€๊ฒฝ ์ฒ˜๋ฆฌ๊ฐ€ ์ œ๊ณตํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ๋งค์šฐ ์–ด์ƒ‰ํ•ฉ๋‹ˆ๋‹ค. ์ฝœ๋ฐฑ ๋ฐ RxJ์˜ ์„ธ๊ณ„๋ฅผ ํ†ตํ•ฉํ•˜๋ ค๋ฉด ๋„ˆ๋ฌด ๋งŽ์€ ๋ณด์ผ๋Ÿฌ ํ”Œ๋ ˆ์ดํŠธ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

์œ„์˜ ์˜๋ฆฌํ•œ ์†”๋ฃจ์…˜ ์ค‘ ์ผ๋ถ€๊ฐ€ ๋งˆ์Œ์— ๋“ค์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์€ ์•„๋‹ˆ์ง€๋งŒ ๋•Œ๋กœ๋Š” 'ํ‘œ์ค€' ๋ฐฉ์‹์„ ์•ฝ๊ฐ„๋งŒ ์žฌ๊ตฌ์„ฑํ•˜๋ฉด ๋ช…ํ™•์„ฑ/์„œํˆฌ๋ฅธ ๋ถ€์กฑ์ด๋ผ๋Š” ์‹ค์ œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ์— ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ๊ฒŒ๋‹ค๊ฐ€ ๋‚˜๋Š” ์—ฌ์ „ํžˆ ์–ธ์  ๊ฐ€ ์ด๊ฒƒ์„ ํ•  ์•„์ด๋น„ ์ดํ›„์˜ '๊ณต์‹์ ์ธ' ๋ฐฉ๋ฒ•์„ ๊ธฐ๋Œ€ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

@Input('isOuterPanel')
set isOuterPanel(value: CheckoutPanelHeaderSettings)
{
    this.inputs.outerPanel$.next(value);
}

@Input('config')
set config(value: CheckoutPanelHeaderSettings)
{
    this.inputs.config$.next(value);
}

// observables for <strong i="6">@Inputs</strong>
inputs = {
    config$: new BehaviorSubject<CheckoutPanelHeaderSettings>(1),
    outerPanel$: new BehaviorSubject<CheckoutPanelHeaderSettings>(1)
};

๊ทธ๋Ÿฐ ๋‹ค์Œ combineLatest(this.service.magicInput$, this.inputs, config$)...... ์™€ ๊ฐ™์€ ๊ฒƒ์„ ์ž…๋ ฅํ•˜์—ฌ RxJS์™€ ์ž…๋ ฅ์„ ๊ฒฐํ•ฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

BehaviorSubject ๋˜๋Š” ReplaySubject ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. BehaviorSubject๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ๋” ์•ˆ์ „ํ•˜๊ณ  ์˜ˆ์ธก ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

  • BehaviorSubject - ๊ธฐ๋ณธ๊ฐ’์ด ์žˆ๋Š” ๊ฒฝ์šฐ ์‚ฌ์šฉ
  • ReplaySubject - ์ž…๋ ฅ ๊ฐ’ ์„ค์ •์„ ์žŠ์–ด๋ฒ„๋ฆฐ ๊ฒฝ์šฐ ๊ด€์ฐฐ ๊ฐ€๋Šฅ ํ•ญ๋ชฉ์ด ๋ฐฉ์ถœ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ์ฝ”๋“œ๋ฅผ ๋ช…ํ™•ํ•˜๊ฒŒ ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋  ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋ชจ๋“  ์ž…๋ ฅ์„ ํ•จ๊ป˜ ๊ทธ๋ฃนํ™”ํ•˜๊ธฐ ๋•Œ๋ฌธ์— this.inputs. ํ•˜๊ณ  ์ž๋™ ์™„์„ฑ์„ ๊ฐ€์ ธ์˜ด์œผ๋กœ์จ '์ˆœ์ˆ˜ํ•œ' ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ์ž…๋ ฅ์ด ๋ฌด์—‡์ธ์ง€ ์‰ฝ๊ฒŒ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


์ด๊ฒƒ์œผ๋กœ ์œ ํ˜• ์•ˆ์ „์„ฑ์„ ๋” ๋†’์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(๋Œ€๋ถ€๋ถ„ ์ด๊ฒƒ์€ ๋‹จ์ง€ ์žฌ๋ฏธ๋ฅผ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค).

// define this globally to 'unwrap' a property 'inputs' with an object of ReplaySubject / BehaviorSubject
export type InputTypes<T extends { inputs: { [key: string]: ReplaySubject<any> | BehaviorSubject<any> } }> = {
    [P in keyof T['inputs']]: T['inputs'][P] extends Observable<infer X> ? X : unknown;
}
// define a local 'InputType' helper above each component
type InputType = InputTypes<CheckoutSmartHeaderComponent>;

๊ทธ๋Ÿฌ๋ฉด @Input ์†์„ฑ์˜ ์œ ํ˜•์„ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

@Input('config')
set config(value: InputType['config$'])
{
    this.inputs.config$.next(value);
}

๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ inputs ๋ฅผ ์ ์šฉํ•˜๋„๋ก ObservableInputs ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ์—ˆ์ง€๋งŒ, ์ด๊ฒƒ์„ ๋ง์ณ๋†“์œผ๋ฉด ์–ด์จŒ๋“  ์ปดํŒŒ์ผ๋˜์ง€ ์•Š์„ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๋ ‡๊ฒŒ ํ•˜์ง€ ์•Š๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

@simeyla ๋„ˆ๋ฌด ๋งŽ์€ ์ƒ์šฉ๊ตฌ.

๋‚˜๋Š” ๋‚ด ์ž์‹ ์˜ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ๊ฑฐ๊ธฐ์— ๋‘๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚ด ์ฒซ ๋ฒˆ์งธ npm ํŒจํ‚ค์ง€์ด๋ฏ€๋กœ ๋ˆ„๋ฝ๋œ ๊ฒƒ์ด ์žˆ๋‹ค๊ณ  ํ™•์‹ ํ•˜์ง€๋งŒ ์—ฌ๊ธฐ์— ์žˆ์Šต๋‹ˆ๋‹ค. https://www.npmjs.com/package/@ng-reactive/async -input

์„ค์น˜

npm install @ng-reactive/async-input --save

์šฉ๋ฒ•

import { Component, Input } from '@angular/core';
import { AsyncInput } from '@ng-reactive/async-input';
import { BehaviorSubject } from 'rxjs';

@Component({
  selector: 'app-hello',
  templateUrl: './hello.component.html',
  styleUrls: ['./hello.component.css']
})
export class HelloComponent {
  @Input() name: string;
  @AsyncInput() name$ = new BehaviorSubject('Default Name');

  constructor() {
    this.name$.subscribe(name => console.log('from async input', name));
  }
}

@ mfp22 ์ •๋ง ์ข‹์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๊ฒƒ์ด ๋‚ด์žฅ๋˜์–ด์„œ๋Š” ์•ˆ๋˜๋Š” ์ด์œ ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์ฐธ๊ณ ๋กœ, ํŒจํ‚ค์ง€์— ๋Œ€ํ•œ npm์˜ github ๋งํฌ๊ฐ€ ์˜ค๋ž˜๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.

https://github.com/mfp22/async-input/tree/master/projects/async-input

๋‚˜๋Š” ์ด๊ฒƒ์ด ๊ฝค ์˜ค๋ž˜๋œ ๋ฌธ์ œ๋ผ๋Š” ๊ฒƒ์„ ์•Œ์ง€๋งŒ ๊ทธ ๊ธฐ๋Šฅ์€ ๊ฝค ๋†€๋ž๊ณ  Angular์—์„œ ๊ทธ๊ฒƒ์„ ๋ณด๊ฒŒ ๋˜์–ด ์ •๋ง ๊ธฐ์ฉ๋‹ˆ๋‹ค.

๋” ๋ฉ‹์ง„ ๊ฒƒ์€ ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ์ž…๋ ฅ์„ ์‚ฌ์šฉํ•˜๋ฉด OnChanges ํ›„ํฌ๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. pairwise rxjs ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ์ž…๋ ฅ์˜ ์ด์ „ ๋ฐ ํ˜„์žฌ ๊ฐ’์„ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@Component({...})
class MyReactiveComponent {
  @ObservableInput() prop: Observable<string>; // Whatever syntax may be...

  // emits [prevValue, currValue] and no OnChanges hook yay!!
  propChanges$ = this.prop.pipe(pairwise());
}

https://github.com/rx-ts/ngrx/blob/master/src/utils/decorators.ts#L56 -L124

์ œ ๊ฐœ์ธ์ ์ธ ๊ตฌํ˜„์œผ๋กœ ์™„๋ฒฝํ•˜๊ณ  ์•„์ฃผ ํ›Œ๋ฅญํ•˜๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๋‚ด์žฅํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ์ •๋ง ๋ฉ‹์ง„ ์ผ์ž…๋‹ˆ๋‹ค.

๋‚ด ํ”„๋กœ์ ํŠธ์—์„œ ๊ฐœ์ธ์ ์œผ๋กœ ์‚ฌ์šฉํ•œ ์†”๋ฃจ์…˜์„ npm ํŒจํ‚ค์ง€๋กœ ๊ฒŒ์‹œํ–ˆ์Šต๋‹ˆ๋‹ค.

https://github.com/futhark/ngx-observable-input

์„ค์น˜

npm install ngx-observable-input

์šฉ๋ฒ•

...
<image-item [url]="currentImageUrl"></image-item>
import { Component, Input } from "@angular/core";
import { ObservableInput } from "ngx-observable-input";
import { Observable } from "rxjs";

@Component({
    selector: "image-item",
    template: `<img [src]="url$ | async" />`
})
export class GalleryComponent {
    @ObservableInput() @Input("url") public url$: Observable<string>;

    ...
}

๋‚˜๋Š” ์ด๊ฒƒ์ด ๊ฝค ์˜ค๋ž˜๋œ ๋ฌธ์ œ๋ผ๋Š” ๊ฒƒ์„ ์•Œ์ง€๋งŒ ๊ทธ ๊ธฐ๋Šฅ์€ ๊ฝค ๋†€๋ž๊ณ  Angular์—์„œ ๊ทธ๊ฒƒ์„ ๋ณด๊ฒŒ ๋˜์–ด ์ •๋ง ๊ธฐ์ฉ๋‹ˆ๋‹ค.

๋” ๋ฉ‹์ง„ ๊ฒƒ์€ ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ์ž…๋ ฅ์„ ์‚ฌ์šฉํ•˜๋ฉด OnChanges ํ›„ํฌ๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. pairwise rxjs ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ์ž…๋ ฅ์˜ ์ด์ „ ๋ฐ ํ˜„์žฌ ๊ฐ’์„ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@Component({...})
class MyReactiveComponent {
  @ObservableInput() prop: Observable<string>; // Whatever syntax may be...

  // emits [prevValue, currValue] and no OnChanges hook yay!!
  propChanges$ = this.prop.pipe(pairwise());
}

์ด๊ฒƒ์€ ๋˜ํ•œ ์ž ์‹œ ๋™์•ˆ ๋‚˜๋ฅผ ๊ดด๋กญํžˆ๋Š” ๋ฌธ์ œ์ด๋ฏ€๋กœ ์กฐ๊ธˆ ์กฐ์‚ฌํ–ˆ๊ณ  ์—ฌ๊ธฐ์—์„œ ์–ธ๊ธ‰ํ•œ ๊ฒƒ๊ณผ ๋™์ผํ•œ ์†”๋ฃจ์…˜์„ ์ƒ๊ฐํ•ด ๋ƒˆ์Šต๋‹ˆ๋‹ค(@gund).

๋‚ด๋ถ€์ ์œผ๋กœ @Input ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ํ™•์žฅํ•˜๊ณ  ์ด๋Ÿฌํ•œ ์ข…๋ฅ˜์˜ ๊ตฌ์„ฑ์„ ํ—ˆ์šฉํ•˜๋Š” ์ž‘์€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ๋„์šฐ๋ฏธ( @ObservableInput )๋ฅผ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค( npm ํŒจํ‚ค์ง€๋กœ๋„ ์‚ฌ์šฉ ). ๊ฐ„๋‹จํ•œ ์˜ˆ์ œ๋กœ ํ…Œ์ŠคํŠธํ•ด ๋ณด์•˜์ง€๋งŒ ํ™•์žฅ ํ”„๋กœ์ ํŠธ์— ์‚ฌ์šฉํ•  ์‹œ๊ฐ„์ด ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ์–ด๋–ค ํ”ผ๋“œ๋ฐฑ์ด๋“  ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค :)

์‚ฌ์šฉ ์˜ˆ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

@Component({
  selector: 'app-test',
  template: `<span>{{ message$ | async }}</span>`
})
class TestComponent {
  @ObservableInput<number>('price') price$: Observable<number>;
  @ObservableInput<string>('name') name$: Observable<string>;

  message$ = combineLatest(this.price$, this.name$).pipe(
    map(([price, name]) => `${name} costs {price}`)
  );
}

๊ทธ๋ฆฌ๊ณ  ์ด ๊ตฌ์„ฑ ์š”์†Œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

<app-test [price]="price"
          [name]="name">
</app-test>

@aleics ์ด๊ฒƒ์ด AOT ์ปดํŒŒ์ผ๋Ÿฌ์™€ ํ•จ๊ป˜ ์ž‘๋™ํ•  ๊ฒƒ์ด๋ผ๊ณ  ํ™•์‹ ํ•ฉ๋‹ˆ๊นŒ?

@aleics ์ด๊ฒƒ์ด AOT ์ปดํŒŒ์ผ๋Ÿฌ์™€ ํ•จ๊ป˜ ์ž‘๋™ํ•  ๊ฒƒ์ด๋ผ๊ณ  ํ™•์‹ ํ•ฉ๋‹ˆ๊นŒ?

์•„๋‹ˆ์š”, ๋ฌผ๋ก  @Input ์†์„ฑ์ด ๋ช…์‹œ์ ์œผ๋กœ ์ •์˜๋˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ธฐ๋ณธ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์›น ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ์™€ ๊ฐ™์ด CUSTOM_ELEMENTS_SCHEMA ์‚ฌ์šฉํ•˜์—ฌ ๋ชจ๋“ˆ์„ ์ •์˜ํ•œ ๋‹ค์Œ ์ปดํŒŒ์ผํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿคฆโ€โ™‚ ๊ณต๊ฐœ๋œ์ง€ 5๋…„์ด ๋œ ์ด๋ฒˆ ํ˜ธ์ž…๋‹ˆ๋‹ค. ๋ฐ˜์‘ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์ ‘๊ทผ ๋ฐฉ์‹์„ ์šฉ์ดํ•˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด ์ด๊ฒƒ์ด ํ•„์š”ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

Ivy๊ฐ€ ๋“œ๋””์–ด ๋‚˜์™”๋„ค์š”. ๋ˆ„๊ตฐ๊ฐ€ ์ด ์ž‘์—…์„ ํ•  ์‹œ๊ฐ„์ด ์žˆ์„ ๊ฒƒ ๊ฐ™์€๋ฐ์š”? ์ œ๋ฐœ ์ œ๋ฐœ ์ œ๋ฐœ!

Omg ๋‚˜๋Š” ์ด๊ฒƒ์ด ๋งค์šฐ ํ•„์š”ํ•˜๋‹ค๊ณ  ๊ตฌ๋…ํ•ฉ๋‹ˆ๋‹ค. ์ž…๋ ฅ ๋ฐ์ดํ„ฐ๋Š” ๋ฐ˜์‘ ์†Œ์Šค๋กœ ๋‚ด๋ณด๋‚ด์•ผ ํ•˜๋ฉฐ ngOnChanges์—์„œ ์ž‘๋™ํ•˜๋„๋ก ํ•˜๋ ค๋ฉด ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฑฐ ์ง„์งœ ๊ธฐ๋Œ€๋œ๋‹ค

Angular๊ฐ€ ์˜คํ”ˆ ์†Œ์Šค๋ผ๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์ง€๋งŒ Google์—์„œ ์‹คํ–‰ํ•˜๋Š” ํ”„๋กœ์ ํŠธ๊ฐ€ 5๋…„ ์ด๋‚ด์— ๋งŽ์€ ๋ณ„ํ‘œ ๋ฐ ์š”์ฒญ๋œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋Š” ๊ฒƒ์ด ์ž˜๋ชป๋˜์—ˆ๊ฑฐ๋‚˜ ์ˆœ์ง„ํ•œ ๊ฒƒ์ž…๋‹ˆ๊นŒ? Google์ด Angular์—์„œ ์ž‘์—…ํ•  ๋” ๋งŽ์€ ๊ฐœ๋ฐœ์ž๋ฅผ ๊ณ ์šฉํ•˜์ง€ ๋ชปํ•˜๋„๋ก ๋ฐฉํ•ดํ•˜๋Š” ์ผ๋ถ€ ์žฌ์ •์  ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

@etay2000 ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. rxjs๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Angular์—์„œ ์ž‘์—…์˜ 75%๋ฅผ ์ˆ˜ํ–‰ํ•œ ๋‹ค์Œ ๊ธฐ๋ณธ์ ์ด๊ณ  ์ผ๋ฐ˜์ ์œผ๋กœ ๊ตฌ์„ฑ ์š”์†Œ ์ž…๋ ฅ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ๊ฐ‘์ž๊ธฐ ์ ˆ์ฐจ๋ฅผ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์ข€ ์›ƒ๊น๋‹ˆ๋‹ค. ์„ธ๊ณ„. ๊ด€์ฐฐ ๊ฐ€๋Šฅ ํ•ญ๋ชฉ์˜ ์„ธ๊ณ„์™€ ์ž‘๋™ํ•  ์ˆ˜ ์—†๋Š” ์ด ์ค‘์š”ํ•œ ํ”„๋กœ์ ํŠธ ๋ถ€๋ถ„์ด ํ•ญ์ƒ ์žˆ์œผ๋ฏ€๋กœ ํ•ญ์ƒ ์ƒ์šฉ๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์‹œ ๊ฒฐํ•ฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•œ ์™„์ „ํ•œ ๊ธฐ๋Šฅ์  ์ ‘๊ทผ ๋ฐฉ์‹์„ ์ ˆ๋Œ€ ๋‹ฌ์„ฑํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. 4๋…„ ๋™์•ˆ ๊ณต๊ฐœ๋œ ์ด ๋ฌธ์ œ๋Š” ์ €๋ฅผ Angular์—์„œ ๋‹ค๋ฅธ ํ”„๋ ˆ์ž„์›Œํฌ๋กœ ๋ชฐ์•„๋„ฃ์€ ์‹ค์šฉ์ฃผ์˜์˜ ๋ถ€์กฑ์„ ์ƒ๊ธฐ์‹œ์ผœ์ค๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ๊ฝค ์œ ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋ชจ๋“  ๊ฒƒ์— rxjs๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด cycle.js๊ฐ€ ๋” ๋‚˜์€ ์†”๋ฃจ์…˜์ผ ์ˆ˜ ์žˆ๊ณ , rxjs๋ฅผ ์ „ํ˜€ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ ค๋ฉด Vue๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Observable์„ ์ ˆ๋ฐ˜์˜ ์‹œ๊ฐ„ ๋™์•ˆ ์‚ฌ์šฉํ•˜๊ณ  ๋‚˜๋จธ์ง€ ์ ˆ๋ฐ˜์€ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์€ ์˜๋ฏธ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๋งค์šฐ ๊ฐ•๋ ฅํ•œ ์ถ”์ƒํ™”๋ฅผ ๋†’์€ ํ•™์Šต ๊ณก์„ ๊ณผ ํ†ตํ•ฉํ•œ ๋‹ค์Œ ์™„์ „ํžˆ ํ†ตํ•ฉํ•˜์ง€ ๋ชปํ•˜๋Š” ๊ฒƒ์€ ๋‹นํ˜น์Šค๋Ÿฌ์šธ ๋ฟ์ž…๋‹ˆ๋‹ค.

์šฐ์„ ์ˆœ์œ„์˜ ์‚ฌ์Šฌ์ด ์ด๋Ÿฐ ์‹์œผ๋กœ ๊ฐ€๋Š” ๊ฒƒ ๊ฐ™์•„

๋‚ด๋ถ€ Google ์‚ฌ์šฉ์ž์˜ ์š”๊ตฌ ์‚ฌํ•ญ -> ๋” ๋น ๋ฅธ ์ปดํŒŒ์ผ๋Ÿฌ์™€ ๊ด€๋ จ๋œ ๋ชจ๋“  ๊ฒƒ -> ๋” ์ž‘์€ ์•ฑ ํฌ๊ธฐ์™€ ๊ด€๋ จ๋œ ๋ชจ๋“  ๊ฒƒ -> ์‹ ๊ทœ ์‚ฌ์šฉ์ž๋ฅผ ํ™”๋‚˜๊ฒŒ ํ•˜์ง€ ์•Š๋Š” ๋ชจ๋“  ๊ฒƒ -> ๊ฐœ๋ฐœ์ž๊ฐ€ ์‹ค์ œ๋กœ ์›ํ•˜๋Š” ๊ฒƒ

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

์ถœ์ฒ˜: https://medium.com/@jeffbcross/jeffs-letter-to-the-angular-team-and-community-5367934a16c9)

๊ฐ€์žฅ ๋งŽ์ด ํˆฌํ‘œ๋œ ๋ฌธ์ œ๋ฅผ ์‚ดํŽด๋ณด์‹ญ์‹œ์˜ค.

์ œ์•ˆ: Observable๋กœ ์ž…๋ ฅ #5689

5๋…„ ์ „ ์ž‘์„ฑ, ๊ด€๋ จ ํŒ€์›์˜ ๋งˆ์ง€๋ง‰ ํšŒ์‹  - 5๋…„ ์ „, ํ˜„์žฌ ์ƒํƒœ ๋ถˆ๋ช….

ํ…œํ”Œ๋ฆฟ์—์„œ ์ฝœ๋“œ ์ด๋ฒคํŠธ ์ŠคํŠธ๋ฆผ ์ง€์› #13248

4๋…„ ์ „์— ์ƒ์„ฑ๋œ ๊ด€๋ จ ํŒ€์›์˜ ๋งˆ์ง€๋ง‰ ํšŒ์‹  - 1๋…„ ์ „, ํ˜„์žฌ ์ƒํƒœ - Ivy๊ฐ€ ์ƒ๋ฅ™ํ•˜๊ธฐ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ œ์•ˆ: ๊ตฌ์„ฑ ์š”์†Œ ์ˆ˜๋ช… ์ฃผ๊ธฐ ํ›„ํฌ๋ฅผ Observable๋กœ ์ œ๊ณต #10185

4๋…„ ์ „ ์ž‘์„ฑ, ๊ด€๋ จ ํŒ€์›์˜ ๋งˆ์ง€๋ง‰ ํšŒ์‹  - 3๋…„ ์ „, ํ˜„์žฌ ์ƒํƒœ ๋ถˆ๋ช….

์ œ์•ˆ: ๊ตฌ์„ฑ ์š”์†Œ ์„ ์–ธ์—์„œ ํ˜ธ์ŠคํŠธ ์š”์†Œ์— ์ง€์‹œ๋ฌธ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ธฐ๋Šฅ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. #8785

4๋…„ ์ „ ์ž‘์„ฑ, ๊ด€๋ จ ํŒ€์›์˜ ๋งˆ์ง€๋ง‰ ํšŒ์‹  - 2๋…„ ์ „, ํ˜„์žฌ ์ƒํƒœ ๋ถˆ๋ช….

as local-val ์—†์ด *ngIf #15280

4๋…„ ์ „ ์ž‘์„ฑ, ๊ด€๋ จ ํŒ€์›์˜ ๋งˆ์ง€๋ง‰ ํšŒ์‹  - 2๋…„ ์ „, ํ˜„์žฌ ์ƒํƒœ ๋ถˆ๋ช….

๋™์  ์ฝ˜ํ…์ธ  ํ”„๋กœ์ ์…˜ ์ง€์› #8563

4๋…„ ์ „ ์ž‘์„ฑ, ๊ด€๋ จ ํŒ€์›์˜ ๋งˆ์ง€๋ง‰ ํšŒ์‹  - 3๋…„ ์ „, ํ˜„์žฌ ์ƒํƒœ ๋ถˆ๋ช….

ng-content ๊ธฐ๋ณธ ์ฝ˜ํ…์ธ  #12530

4๋…„ ์ „์— ์ž‘์„ฑ๋˜์—ˆ์œผ๋ฉฐ ๊ด€๋ จ ํŒ€์›์˜ ๋งˆ์ง€๋ง‰ ํšŒ์‹  - ํ•œ ๋ฒˆ๋„, ํ˜„์žฌ ์ƒํƒœ๋ฅผ ์•Œ ์ˆ˜ ์—†์Œ.

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

๋‚ด ์•ฑ์€ ๋ฐ˜์ฏค ๊ตฌ์šด(๋‹จ์ˆœํžˆ ๊ธฐ์ˆ ์ ์ธ ์ œํ•œ์œผ๋กœ ์ธํ•ด ์ผ๋ถ€๋Š” ์ฝ”์–ด์—์„œ๋งŒ ์ œ๋Œ€๋กœ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Œ) "ํด๋ฆฌํ•„"๋กœ ๊ฐ€๋“ ์ฐจ ์žˆ๊ณ  ์ด๋Ÿฌํ•œ ๋ฌธ์ œ์˜ ๋Œ€๋ถ€๋ถ„์„ ํ•ดํ‚นํ•˜์—ฌ ์–ธ์  ๊ฐ€๋Š” ์•ต๊ทค๋Ÿฌ ๋„ค์ดํ‹ฐ๋ธŒ์— ๋น ์งˆ ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. ๋ฐ”๊ฟ” ๋†“์Œ. ํ•˜์ง€๋งŒ ์™ ์ง€ ์˜ค์ง€ ์•Š์„ ๊ฒƒ ๊ฐ™๋‹ค.

์˜ˆ, ๊ฐ€์žฅ ํฐ ๋ฐ˜์‘์„ฑ/๊ฐœ๋ฐœ์ž ๊ฒฝํ—˜ ๊ด€๋ จ ๋ฌธ์ œ์˜ ์ƒํƒœ๋ฅผ ๋‹ค๋ฃจ๋Š” ๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๋ฌผ์ด ์ •๋ง ๊ฐ์‚ฌํ•  ๊ฒƒ์ด๋ผ๊ณ  ๊ฐ€์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์ด ๊ธฐ๋Šฅ์˜ ์ฒซ ๋ฒˆ์งธ ๋ฒ„์ „์„ ์ง์ ‘ ์ฝ”๋”ฉํ•ด ๋ณด๋Š” ๊ฒƒ์€ ์–ด๋–ป์Šต๋‹ˆ๊นŒ? ์ €๋Š”
covid ๋•Œ ์ง€๋ฃจํ•ด ์ฃฝ์–ด, ๋ˆ„๊ฐ€ ๋‚˜์™€ ํ•จ๊ป˜ํ•˜๊ณ  ์‹ถ์–ด?

์˜ˆ๋ฅผ ๋“ค์–ด ์—ฌ๋Ÿฌ ์‚ฌ๋žŒ์ด ์ด๋ฏธ ํ–ˆ์Šต๋‹ˆ๋‹ค. https://github.com/insidewhy/observable-input

์ด๋“ค ๋Œ€๋ถ€๋ถ„์˜ ๋ฌธ์ œ๋Š” ํšจ์œจ์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•˜๋ ค๋ฉด ์ปดํŒŒ์ผ๋Ÿฌ๋‚˜ angular์˜ ๋‹ค๋ฅธ ๋‚ด๋ถ€ ๋ถ€๋ถ„์„ ์ˆ˜์ •ํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

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

@ganqqwerty ํ•ด๋‹น ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ ์ „์— Angular ๋‚ด๋ถ€์—์„œ ๊ตฌํ˜„ํ•˜๋ ค๊ณ  ํ–ˆ์Šต๋‹ˆ๋‹ค. Angular๋Š” ๋งค์šฐ ๋ณต์žกํ•ฉ๋‹ˆ๋‹ค. ๊ณต์ •ํ•˜๊ฒŒ ๋งํ•˜์ž๋ฉด, ์ฝ”๋“œ๋Š” React์™€ 500์ค„์งœ๋ฆฌ ๋ฏธ์นœ ๊ธฐ๋Šฅ๋ณด๋‹ค ํ›จ์”ฌ ๋” ์ฝ๊ธฐ ์‰ฝ๊ณ  ์ดํ•ดํ•˜๊ธฐ ์‰ฝ์ง€๋งŒ "์ •๊ต"ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ทธ๊ฒƒ์ด ๊ฐ€์น˜๊ฐ€ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค๋ฉด ๋‚˜๋Š” ์—ฌ์ „ํžˆ ๊ทธ ๊ตฌํ˜„์„ ์œ„ํ•ด ๋…ธ๋ ฅ์„ ๊ธฐ์šธ์˜€์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์œ„์—์„œ @fxck๊ฐ€ ๋ฐ˜๋ณต๋œ ์ •ํ™•ํ•œ ์ด์œ  ๋•Œ๋ฌธ์— ๊ฐ€์น˜๊ฐ€ ์žˆ๋‹ค๊ณ  ๋ณด์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Angular ํŒ€์€ ์ปค๋ฎค๋‹ˆํ‹ฐ์˜ ๋ง์„ ๋“ฃ์ง€ ์•Š๊ณ  ์ผ๋ฐ˜์ ์œผ๋กœ Angular์˜ ์œ ์šฉ์„ฑ์— ๋Œ€ํ•ด ์‹ ๊ฒฝ ์“ฐ์ง€ ์•Š๊ณ  ์ตœ์ ํ™”์™€ ์„ฑ๋Šฅ์— ์ง€์†์ ์œผ๋กœ ์ง‘์ฐฉํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” 5๋…„ ์ „์— ์‹œ์—ฐ๋œ ๊ฐ„๋‹จํ•œ ๋ฌธ์ œ์— ๋Œ€ํ•ด ์ƒ์šฉ๊ตฌ๋ฅผ ๊ตฌํ˜„ํ•˜๋„๋ก ๊ฐ•์š”ํ•  ๋•Œ ์ž˜ ์ˆ˜ํ–‰๋˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ์— ๋Œ€ํ•ด์„œ๋Š” ์‹ ๊ฒฝ ์“ฐ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๋‚˜๋Š” Angular์— ๋Œ€ํ•œ ๊ด€์‹ฌ์„ ๋ฉˆ์ถ”๊ณ , ๋‚ด๊ฐ€ ์ด๋ฏธ ์ž‘์—…ํ•˜๊ณ  ์žˆ๋Š” ํ”„๋กœ์ ํŠธ๋ฅผ ์ง€์›ํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ์ตœ์†Œํ•œ์˜ ๋…ธ๋ ฅ์„ ๊ตฌํ˜„ํ•˜๊ณ , ๋ฏธ๋ž˜์˜ ๋ชจ๋“  ํ”„๋กœ์ ํŠธ์—์„œ ๊ฐ€๋Šฅํ•˜๋ฉด ์–ธ์ œ ์–ด๋””์„œ๋‚˜ ์ด๋ฅผ ํ”ผํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ Angular๋งŒ์˜ ๋ฌธ์ œ๊ฐ€ ์•„๋‹ˆ๋ผ Google์˜ ๋งŽ์€ ์ œํ’ˆ์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ์™€ @fxck๊ฐ€ ์œ„์— ๋‚˜์—ด๋œ ๋‹ค๋ฅธ ๋ฌธ์ œ๋Š” Google์˜ ๊ณ ์œ ํ•œ ๋ฌธ์ œ์— ๋Œ€ํ•œ ๋” ๋งŽ์€ ์˜ˆ์ž…๋‹ˆ๋‹ค. Dart ๋˜๋Š” GoLang์„ ๋ณด๋ฉด ๊ฐœ๋ฐœ์ž๊ฐ€ ์ผ๋ฐ˜์ ์œผ๋กœ ์ง๋ฉดํ•˜๋Š” ๋งค์šฐ ์ž˜ ์•Œ๋ ค์ง„ ๋ฌธ์ œ๋ฅผ ์ œ๊ธฐํ•˜๊ณ  ๋ฌธ์ œ๊ฐ€ 5๋…„ ์ด์ƒ ์ง€์†๋˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ด๊ฒƒ์ด ์ถ”๊ฐ€๋˜์–ด์•ผ ํ•œ๋‹ค๋Š” ๋ฐ ๋™์˜ํ•˜์ง€๋งŒ, ์™€์šฐ, ์ด ์Šค๋ ˆ๋“œ์— ๋Œ€ํ•œ ์ฆ์˜ค๊ฐ€ ์กฐ๊ธˆ ๋งŽ์Šต๋‹ˆ๋‹ค. ์ œ ๋ง์€ ์šฐ๋ฆฌ๊ฐ€ ๋ช‡ ์ค„์˜ ์ฝ”๋“œ๋ฅผ ์ ˆ์•ฝํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌด์–ธ๊ฐ€๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•˜๊ณ  ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด์ œ @Input์œผ๋กœ ์žฅ์‹๋œ setter์™€ ๊ฐ’์„ ํ‘ธ์‹œํ•˜๋Š” ์ž์‹ ์˜ ์ฃผ์ œ๋กœ ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ์ž…๋ ฅ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

https://github.com/angular/angular/issues/5689#issuecomment -507001686

๋„ˆ๋ฌด ๋งŽ์€ ์ƒ์šฉ๊ตฌ๋ผ๋ฉด ์ด๋ฏธ ๊ฐ„๋‹จํ•œ ํƒ€์‚ฌ ์˜ต์…˜์ด ์žˆ์Šต๋‹ˆ๋‹ค.

https://github.com/Futhark/ngx-observable-input

์ €๋Š” Angular์˜ ๊ฐœ๋ฐœ์— ๋งŒ์กฑํ•˜๋ฉฐ ์ด๋Ÿฌํ•œ ์‚ฌ์†Œํ•œ(๋ฐ”๋žŒ์งํ•œ) ๊ธฐ๋Šฅ ๋•Œ๋ฌธ์— ๋†€๋ž๋„๋ก ์™„์ „ํ•œ ๊ธฐ๋Šฅ๊ณผ ์•ˆ์ •์ ์ธ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ํฌ๊ธฐํ•˜์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ผ๋ฐ˜์ ์ธ ๋ฌธ์ œ๋Š” ์ฃผ๋กœ ์‚ฌ๋žŒ๋“ค์ด ๊ทธ๊ฒƒ์„ ๋ณด๋Š” ๊ด€์ ์—์„œ์ž…๋‹ˆ๋‹ค. ๋ˆ„๊ตฐ๊ฐ€์—๊ฒŒ๋Š” ๋ช‡ ์ค„์˜ ์ฝ”๋“œ๋กœ ๋ฌด์—‡์ด๋“  ๋ณ€๊ฒฝ/์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ๋งค์šฐ ๊ฐ„๋‹จํ•ด ๋ณด์ด์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” ๋” ํฐ ๋ฒ”์œ„์™€ ๋งŽ์€ ๋ถ€์ž‘์šฉ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋“ค ๋ชจ๋‘๋Š” ๊ณ ๋ ค๋˜์–ด์•ผ ํ•˜๊ณ  ํ•ญ์ƒ ๊ทธ๋ ‡๋“ฏ์ด ์ฃผ์ œ์˜ ๋ผ์ธ์€ ๊ธธ๊ณ  ๋ชจ๋“  ๊ฒƒ์€ ์•ฝ๊ฐ„์˜ ๋น„์šฉ, ๋ถ€๊ฐ€๊ฐ€์น˜ ๋ฐ ์šฐ์„  ์ˆœ์œ„๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐœ์ธ์ ์œผ๋กœ ์ด๋Ÿฌํ•œ ๋ชจ๋“  ๋ฌธ์ œ๊ฐ€ ์ฆ‰์‹œ ํ•ด๊ฒฐ๋  ๊ฒƒ์œผ๋กœ ๊ธฐ๋Œ€ํ•˜์ง€๋Š” ์•Š๋Š”๋‹ค๋Š” ์ ์„ ์ง€์ ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์ด์ œ Ivy๊ฐ€ ๋ฐฉํ•ด๊ฐ€ ๋˜์ง€ ์•Š๊ณ  ์ž ์‹œ ๋™์•ˆ ์•ผ์™ธ ํ™œ๋™์„ ํ•˜์ง€ ์•Š์•˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ƒ์œ„ 25๊ฐœ ์ฐฌ์„ฑ ๋ฌธ์ œ์— ๋Œ€ํ•œ ์ผ์ข…์˜ ๊ณต์‹ ์—…๋ฐ์ดํŠธ๊ฐ€ ๊ฒŒ์‹œ๋˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

๋‚ด ๋ง์€, ์ด ๊ทœ๋ชจ์˜ ํ”„๋กœ์ ํŠธ๊ฐ€ ํ”„๋กœ์ ํŠธ ๊ด€๋ฆฌ์—์„œ ์ตœ์šฐ์„  ์ˆœ์œ„์™€ ์ƒ์œ„ 25๊ฐœ(๋˜๋Š” ๋ฌด์—‡์ด๋“ ) ํˆฌํ‘œ๋œ ๋ชจ๋“  ๋ฌธ์ œ์— ๋Œ€ํ•œ ์ผ์ข…์˜ ๊ณ„ํš์„ ๊ณ ๋ คํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์ฐพ์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋“ค ์ค‘ ๋Œ€๋ถ€๋ถ„์—๋Š” effort ํƒœ๊ทธ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๋ฌผ์„ ์ž‘์„ฑํ•˜๊ณ  ์ปค๋ฎค๋‹ˆํ‹ฐ์— ๊ท€ํ•˜๊ฐ€ ์ด์— ๋Œ€ํ•ด ์•Œ๊ณ  ์žˆ์œผ๋ฉฐ ์ด์— ๋Œ€ํ•œ ์ผ์ข…์˜ ๊ณ„ํš์ด ์žˆ์Œ์„ ์•Œ๋ฆฌ์‹ญ์‹œ์˜ค.

๋‚˜๋Š” ํ™•์‹คํžˆ Angular๋ฅผ ํฌ๊ธฐํ•˜์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ชจ๋“  ๋‹จ์  ๋•Œ๋ฌธ์— ์—ฌ์ „ํžˆ ๋‹ค๋ฅธ ๋ชจ๋“  ๋Œ€์•ˆ๋ณด๋‹ค ํ›จ์”ฌ ๋” ์ข‹์•„ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ "์ปค๋ฎค๋‹ˆํ‹ฐ ๊ด€๊ณ„ ๊ด€๋ฆฌ"(ํŠนํžˆ github์—์„œ)๊ฐ€ ๋ถ€์กฑํ•˜๋‹ค๊ณ  ๋งํ•˜๋Š” ๊ฒƒ์ด ํƒ€๋‹นํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

// ํŽธ์ง‘ํ•˜๋‹ค

์ข‹์€ ์‚ฌ๋žŒ๋“ค์ด ์ด ์„ค๋ฌธ์กฐ์‚ฌ๋ฅผ ์ž‘์„ฑํ•ด ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ํ˜„์žฌ ์ƒํ™ฉ๊ณผ ๊ณ ๋ คํ•œ ๋ชจ๋“  ์‚ฌํ•ญ์„ ๊ณ ๋ คํ•  ๋•Œ ์ด๋Ÿฌํ•œ ๋ฌธ์ œ ์ค‘ ๊ฐ€์žฅ ํฐ ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š” ๊ฒƒ์€ / ๊ฐœ๋ฐœ์ž ๊ฒฝํ—˜์„ ๊ฐ€์žฅ ํ–ฅ์ƒ์‹œํ‚ฌ ๊ฒƒ์ž…๋‹ˆ๋‹ค https://forms.gle/cprhx239kuqwWd5M8

@fxck ์ž‘์„ฑ

๋‚˜๋Š” ํ™•์‹คํžˆ Angular๋ฅผ ํฌ๊ธฐํ•˜์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ชจ๋“  ๋‹จ์  ๋•Œ๋ฌธ์— ์—ฌ์ „ํžˆ ๋‹ค๋ฅธ ๋ชจ๋“  ๋Œ€์•ˆ๋ณด๋‹ค ํ›จ์”ฌ ๋” ์ข‹์•„ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ "์ปค๋ฎค๋‹ˆํ‹ฐ ๊ด€๊ณ„ ๊ด€๋ฆฌ"(ํŠนํžˆ github์—์„œ)๊ฐ€ ๋ถ€์กฑํ•˜๋‹ค๊ณ  ๋งํ•˜๋Š” ๊ฒƒ์ด ํƒ€๋‹นํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ๊ทธ ๋ฌธ์žฅ์ด ๋‚ด ์ƒ๊ฐ์„ ์™„๋ฒฝํ•˜๊ฒŒ ์š”์•ฝํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

@chriszrc ์ €๋Š” ์ด ์Šค๋ ˆ๋“œ์˜ ์–ด๋–ค ๊ฒƒ๋„ '์ฆ์˜ค'๋กœ ํ•ด์„ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์‚ฌ๋žŒ๋“ค์ด ๋งˆ์นจ๋‚ด ํ•œ ๋ฒˆ์— ๋ช‡ ๋…„ ๋™์•ˆ ๋ฌธ์ œ๋ฅผ ์ •๊ธฐ์ ์œผ๋กœ ๋ฌด์‹œํ•˜๋Š” Angular๋กœ ์ขŒ์ ˆ๊ฐ์„ ํ‘œ์ถœํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ํŠนํžˆ ์ด ๋ฌธ์ œ์— ๊ด€ํ•œ ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์–ด๋–ค ํ˜•ํƒœ์˜ ์ปค๋ฎค๋‹ˆํ‹ฐ ์ƒํ˜ธ ์ž‘์šฉ์„ ์œ ์ง€ํ•˜๋Š” ์›์น™์— ๊ด€ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. Angular ํŒ€์ด ๋ชจ๋“  ์‚ฌ๋žŒ์—๊ฒŒ ๊ฐ€์žฅ ์ข‹์€ ๊ฒƒ์ด ๋ฌด์—‡์ธ์ง€ ์•Œ๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐœ๋ฐœ์ž ์š”์ฒญ์„ ๋ฌด์‹œํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•  ์ •๋„๋กœ ๋‹ค๋ฅธ ๋ˆ„๊ตฌ๋ณด๋‹ค ํ›จ์”ฌ ๋›ฐ์–ด๋‚œ ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผ๋ฉ๋‹ˆ๊นŒ?

@chriszrc ์ด ์Šค๋ ˆ๋“œ์—๋Š” ์ฆ์˜ค๊ฐ€ ์ „ํ˜€ ์—†๊ณ  ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋Š” ์ขŒ์ ˆ๋งŒ @fxck ๊ฐ€ ์œ„์—์„œ ์ œ๊ธฐํ•œ ๋Œ€์ค‘์ ์ธ ๋ฌธ์ œ์˜ ์ค‘์š”ํ•œ ๋ชจ์Œ์ด ๋ฌด์‹œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š” ์—ฌ๋Ÿฌ๋ถ„, ์ด ์Šค๋ ˆ๋“œ์˜ ์นจ๋ฌต์— ๋Œ€ํ•ด ์‹ค๋ก€ํ•ฉ๋‹ˆ๋‹ค. ํ•œ๋™์•ˆ ์šฐ๋ฆฌ๊ฐ€ ๋ฐ›์•„์˜จ ๋‘ ๊ฐ€์ง€ ์ง๊ต ์š”์ฒญ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  1. ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ๋” ๋‚˜์€ ์ผ๊ธ‰ RxJS ์ง€์›
  2. Angular์˜ RxJS๊ฐ€ ์ ์–ด ์ž ์žฌ์ ์œผ๋กœ ์„ ํƒ ์‚ฌํ•ญ์ด ๋ฉ๋‹ˆ๋‹ค.

๋‘ ์š”์ฒญ ๋ชจ๋‘ ์šฐ๋ฆฌ์˜ ๋ ˆ์ด๋”์— ์žˆ์œผ๋ฉฐ ๋‘˜ ๋‹ค ์žฅ๋‹จ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ฒซ ๋ฒˆ์งธ ๋ฐฉํ–ฅ์œผ๋กœ ๊ฐ€๋ฉด ํ‘œํ˜„๋ ฅ์ด ํ’๋ถ€ํ•˜๊ณ  ์˜๋ฏธ๊ฐ€ ํ’๋ถ€ํ•œ RxJS API๋ฅผ ์ฒ˜์Œ ์ ‘ํ•˜๋Š” ์—”์ง€๋‹ˆ์–ด๊ฐ€ ํ”„๋ ˆ์ž„์›Œํฌ์— ์ ‘๊ทผํ•˜๊ธฐ ์–ด๋ ต๊ฒŒ ๋งŒ๋“ค ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด Angular ์•ฑ์˜ ๋ชจ๋“  ๊ณณ์—์„œ RxJS๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ์šฐ๋ คํ•˜๊ณ  ์žˆ์–ด ๊ฒฝํ—˜ ์ˆ˜์ค€์ด ๋‹ค๋ฅธ ํŒ€์›๋“ค์ด ์†Œ์Šค ์ฝ”๋“œ๋ฅผ ์ฝ๊ธฐ ์–ด๋ ต๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

๋™์‹œ์— ์šฐ๋ฆฌ๋Š” ์ด๋ฏธ ๋งŽ์€ ๋ฐ˜์‘ํ˜• API๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์ง€๋งŒ Angular์—์„œ ์ œ๊ณตํ•˜๋Š” ์ผ๋ถ€ ๊ธฐ๋ณธ ์š”์†Œ๋Š” ์™„์ „ํžˆ ํ•„์ˆ˜์ ์ด๋ฉฐ ๋ชจ๋“  ๊ฒƒ์ด ์ž˜ ์—ฐ๊ฒฐ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฆ‰, ๋ฐ˜์‘์„ฑ ์ง€์›์„ ๊ฐœ์„ ํ•˜๋Š” ๊ฒƒ์ด ์ด์น˜์— ๋งž์ง€๋งŒ ์ด๊ฒƒ์ด Angular ํ•ต์‹ฌ์˜ ์ผ๋ถ€์ด๊ฑฐ๋‚˜ ์šฐ๋ฆฌ๊ฐ€ ๊ธด๋ฐ€ํ•˜๊ฒŒ ํ˜‘๋ ฅํ•˜๋Š” ์ปค๋ฎค๋‹ˆํ‹ฐ ํ”„๋กœ์ ํŠธ(์˜ˆ: ngrx - Angular์˜ ๋ฐ˜์‘ ํ™•์žฅ)์— ์œ„์ž„๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?

์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์€ ์—ฌ๋Ÿฌ ๊ฐ€์ง€๊ฐ€ ์žˆ์ง€๋งŒ ๋‹ค์Œ์„ ๊ณ ๋ คํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  • ์ด์ „ ๋ฒ„์ „๊ณผ์˜ ํ˜ธํ™˜์„ฑ - ์†Œ์Šค ์ฝ”๋“œ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๊ต์œก ๋ฆฌ์†Œ์Šค
  • ํ•™์Šต ๊ณก์„ 
  • ํ˜„์žฌ API์™€์˜ ์ผ๊ด€์„ฑ
  • ํ”„๋กœ์ ํŠธ ๊ฐ„ ์ผ๊ด€์„ฑ
  • ์„ฑ๋Šฅ - ๋Ÿฐํƒ€์ž„ ๋ฐ ์ดˆ๊ธฐ ๋กœ๋“œ ์‹œ๊ฐ„ ๋ชจ๋‘

์šฐ๋ฆฌ๋Š” ๊ฐ€์žฅ ๋งŽ์ด ์š”์ฒญ๋˜๊ณ  ์šฐ๋ฆฌ๊ฐ€ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ์˜ํ–ฅ๋ ฅ ์žˆ๋Š” ๊ฐœ์„  ์‚ฌํ•ญ์„ ์‚ดํŽด๋ณด๊ณ  ๋ช‡ ๊ฐ€์ง€ ์ฃผ์š” GitHub ๋ฌธ์ œ์˜ ์šฐ์„  ์ˆœ์œ„๋ฅผ ์ง€์ •ํ•˜๋Š” ๊ณผ์ •์— ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ด๊ฒƒ์ด ๋” ๋„์ „์ ์ธ ๊ฒƒ ์ค‘ ํ•˜๋‚˜๋ผ๊ณ  ๋งํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๋‚ ์งœ๋ฅผ ์•ฝ์†ํ•˜๊ธฐ๊ฐ€ ์–ด๋ ต์Šต๋‹ˆ๋‹ค.

@mgechev ์‘๋‹ต

rxjs์™€ ๋ฐ˜์‘ํ˜• API๊ฐ€ ๋‹ค๋ฅธ ํ™•์žฅ ํ”„๋กœ๊ทธ๋žจ์œผ๋กœ ๋ถ„ํ• ๋˜๋Š” ๊ฒฝ์šฐ(๋‚ด ๊ฐœ์ธ ํˆฌํ‘œ๊ฐ€ ์•„๋‹˜)

๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ์ผ์–ด๋‚  ๊ฒƒ์ด๋ผ๊ณ  ๋งํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. ๋‚ด ์˜๊ฒฌ์—์„œ ๋‚˜๋Š” ํ”„๋กœ์ ํŠธ์˜ ๋ฒ”์œ„์™€ ์šฐ๋ฆฌ๊ฐ€ ๊ฐ€์ง„ ๋‹ค์–‘ํ•œ ๊ณ ๋ ค ์‚ฌํ•ญ์„ ๋ณด์—ฌ์ค„ ์ˆ˜ ์žˆ๋„๋ก ๋ถˆ์™„์ „ํ•œ ๋Œ€์•ˆ ๋ชฉ๋ก์„ ๊ณต์œ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

@mgechev ์ •๋ง ๋‹ต๋ณ€ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ Angular์˜ ๋ฆฌ์•กํ‹ฐ๋ธŒ ๋ถ€๋ถ„์ด ์ปค๋ฎค๋‹ˆํ‹ฐ ํ”„๋กœ์ ํŠธ๋กœ ์–ด๋–ป๊ฒŒ๋“  "๊ฐ•๋“ฑ"๋œ๋‹ค๋ฉด ๋ฆฌ์•กํ‹ฐ๋ธŒ๊ฐ€ Angular์˜ 2๊ธ‰ ์‹œ๋ฏผ์ด ๋œ๋‹ค๋Š” ๋œป์ด ์•„๋‹๊นŒ์š”?

@mgechev ๋‹น์‹ ์˜ ๊ณ ํ†ต์ด ํ•œ ๋ฒˆ์— ๋‘ ๋ฐฉํ–ฅ์œผ๋กœ ์ฐข์–ด์ง€๋Š” ๊ฒƒ์„ ๋Š๋‚๋‹ˆ๋‹ค. ์šฐ๋ฆฌ ํŒ€์€ ์‹ค์ œ๋กœ ๋ช…๋ นํ˜•/๋ฐ˜์‘ํ˜• ์กฐ๊ฐ์„ ๋‚˜๋ˆ„๋Š” ๊ฒƒ์— ๋ฐ˜๋Œ€ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ๋ถ„ํ• ์— ๋Œ€ํ•œ ์š”๊ตฌ ์‚ฌํ•ญ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ๋ช…๋ น์  ์š”๊ตฌ์™€ ๋ฐ˜์‘์  ์š”๊ตฌ๋ฅผ ๋ชจ๋‘ ์‚ฌ์šฉํ•˜์—ฌ ๊ณ ์œ ํ•œ ๋Š๋‚Œ์„ ์ฃผ๊ณ  ์–ด๋Š ์ชฝ๋„ ๊ณ ์ •๋œ ๋Š๋‚Œ์„ ์ฃผ์–ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค.
  • ๋ฐ˜์‘์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๋Š” ํŠน์ • ์ƒํƒœ ๊ด€๋ฆฌ ์†”๋ฃจ์…˜๊ณผ ์—ฐ๊ฒฐ๋˜์ง€ ์•Š์Œ(ํ˜„์žฌ akita๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก 50๊ฐœ ์ด์ƒ์˜ ํ”„๋กœ์ ํŠธ๋ฅผ ๋ชจ๋‘ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ–ˆ์Šต๋‹ˆ๋‹ค
  • ๋‘ ์˜ต์…˜์„ ๋™์‹œ์— ๋‹จ์ผ ๋ฒ„์ „์œผ๋กœ ์ถœ์‹œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(์ง€์—ฐ/์ง€์—ฐ ์—†์Œ).
  • "์ฆ๊ฒจ์ฐพ๊ธฐ"๋ž€ ์žˆ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. Angular๊ฐ€ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ชจ๋“  ์ž‘์—…์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋Š๋ผ๋ฉด์„œ ์–‘์ชฝ ์„ธ๊ณ„์—์„œ ๋ชจ๋‘ ์ž‘๋™ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • Angular ํŒ€์ด ๋’ท๋ฐ›์นจํ•˜๋Š” ๋‘ ๊ฐ€์ง€ ์ ‘๊ทผ ๋ฐฉ์‹ ๋ชจ๋‘์— ๋Œ€ํ•œ ์™„์ „ํ•œ ๊ณต์‹ ์ง€์›(์šฐ๋ฆฌ์˜ ๊ฒฝํ—˜์— ๋”ฐ๋ฅด๋ฉด ์ด๊ฒƒ์€ ๊ณ ๊ฐ์˜ ํ•˜๋“œ ์Šคํ†ฑ ๊ณ ๊ฐ ์š”๊ตฌ ์‚ฌํ•ญ์ž„)

์œ„์˜ ๋‚ด์šฉ์„ ๊ธฐ๋ฐ˜์œผ๋กœ:

  • 2๊ฐ€์ง€ ์ฃผ์š” ์˜ต์…˜์ด ์žˆ์Šต๋‹ˆ๋‹ค.

    • ํ•ต์‹ฌ ๋ช…๋ นํ˜• + ์• ๋“œ์˜จ ๋ฐ˜์‘ํ˜•

    • ํ•ต์‹ฌ ๋ฐ˜์‘ + ์• ๋“œ์˜จ ๋ช…๋ น

  • ํ•„์ˆ˜์ฒ˜๋Ÿผ ๋ณด์ด๋„๋ก ๋ฆฌ์•กํ‹ฐ๋ธŒ๋ฅผ ๋ž˜ํ•‘ํ•˜๋Š” ๊ฒƒ์€ ๋งค์šฐ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋Œ€์˜ ๊ฒฝ์šฐ๋Š” ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ๋”ฐ๋ผ์„œ ์šฐ๋ฆฌ๋Š” ํ•ต์‹ฌ์—์„œ ๋ฐ˜์‘ํ˜•์„ ์‚ฌ์šฉํ•˜๊ณ  ์• ๋“œ์˜จ์— ๋ช…๋ นํ˜• API๋ฅผ ํฌํ•จํ•˜๋„๋ก ํˆฌํ‘œํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.
  • ์ง€์—ฐ์ด ์—†๊ณ  ์ฆ๊ฒจ์ฐพ๊ธฐ ์š”๊ตฌ ์‚ฌํ•ญ์ด ์—†๊ณ  ๊ณต์‹ ์ง€์›์ด ํ•„์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์• ๋“œ์˜จ์ด ์–ด๋–ป๊ฒŒ ์ปค๋ฎค๋‹ˆํ‹ฐ ํ”„๋กœ์ ํŠธ๊ฐ€ ๋  ์ˆ˜ ์žˆ๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ์œ„์˜ ๋‚ด์šฉ์ด ์šฐ๋ฆฌ์˜ ์„ธ๊ณ„๊ด€์ด๋ฉฐ ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค๋„ ๋งŽ๋‹ค๋Š” ๊ฒƒ์„ ์ดํ•ดํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ธ€์„ ์“ฐ๋Š” ์ด์œ ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • Reactive๋ฅผ ์ปค๋ฎค๋‹ˆํ‹ฐ ํ”„๋กœ์ ํŠธ๋กœ ์ถ”์ถœํ•˜๋Š” ๊ฒฝ์šฐ ์šฐ๋ฆฌ๋Š” 50๊ฐœ ์ด์ƒ์˜ ์†”๋ฃจ์…˜์„ ๋‹ค๋ฅธ ํ”„๋ ˆ์ž„์›Œํฌ๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ๋”ฐ๋ผ์„œ ๋‹ค๋ฅธ ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ๊ฐœ๋ฐœ์ž๋ฅผ ์žฌ๊ต์œกํ•˜๊ณ  ํ•ด๋‹น ํ”„๋กœ์ ํŠธ๋ฅผ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•  ์‹œ๊ฐ„์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋„๋ก ์ตœ๋Œ€ํ•œ ๋นจ๋ฆฌ (์ปค๋ฎค๋‹ˆํ‹ฐ)์— ์ด ํ”„๋กœ์ ํŠธ์˜ ์œ„์น˜๋ฅผ โ€‹โ€‹์•Œ๋ ค๋‹ฌ๋ผ๊ณ  ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค.

๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•ด์ฃผ์„ธ์š”

@mgechev ๋‚˜๋Š” ๋‹น์‹ ์˜ ๊ฑฑ์ •์„ ์ดํ•ดํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ์ด ์ œ์•ˆ์€ ๋‘ ์„ธ๊ณ„๋ฅผ ์ดˆ๋ณด์ž ๊ฐœ๋ฐœ์ž ์ธํ„ฐํŽ˜์ด์Šค๋กœ ํ†ต์ผ๋˜๊ณ  ์ง๊ด€์ ์œผ๋กœ ๊ฒฐํ•ฉํ•˜๋Š” ๊ฒƒ์— ๊ด€ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‘˜ ์ค‘ ํ•˜๋‚˜๋ฅผ ์„ ํƒํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์กฐํ•ฉ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๊ฐœ๋ฐœ์ž x๋Š” ๋ฉ‹์ง„ ๋ฐ˜์‘ํ˜• ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋นŒ๋“œํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ฐœ๋ฐœ์ž y๋Š” ๊ทธ๋‹ค์ง€ ๋ฐ˜์‘์ ์ด์ง€ ์•Š์€ ํ”„๋กœ์ ํŠธ์—์„œ ๊ทธ๊ฒƒ์„ ์‚ฌ์šฉํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ์™œ ์•ˆ ๋ผ? ์™œ ๊ทธ๋Š” ngrx ์ ‘์ฐฉ์ œ์— ์˜์กดํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?
๋‘ ์„ธ๊ณ„์˜ ์ฐจ์ด์ ์€ ๊ถ๊ทน์ ์ธ ์Šค๋งˆํŠธ ๊ตฌ์„ฑ ์š”์†Œ์™€ ์ค‘์•™ ์ƒํƒœ ์ €์žฅ์†Œ์— ์ƒํƒœ๋ฅผ ์ €์žฅ/๊ด€๋ฆฌํ•˜๋Š”์ง€ ์—ฌ๋ถ€์ด๋ฉฐ ์ด๊ฒƒ์ด ngrx๊ฐ€ ์žˆ์–ด์•ผ ํ•˜๋Š” ๋ถ€๋ถ„์ด์ง€๋งŒ ๊ตฌ์„ฑ ์š”์†Œ์˜ ๊ฒฝ์šฐ ํ”„๋ ˆ์ž„์›Œํฌ ์ž์ฒด๊ฐ€ ์ธ์—์ด๋ธ”๋Ÿฌ์—ฌ์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

ํ•œ๋™์•ˆ ์šฐ๋ฆฌ๊ฐ€ ๋ฐ›์•„์˜จ ๋‘ ๊ฐ€์ง€ ์ง๊ต ์š”์ฒญ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  1. ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ๋” ๋‚˜์€ ์ผ๊ธ‰ RxJS ์ง€์›
  2. Angular์˜ RxJS๊ฐ€ ์ ์–ด ์ž ์žฌ์ ์œผ๋กœ ์„ ํƒ ์‚ฌํ•ญ์ด ๋ฉ๋‹ˆ๋‹ค.

์–ด๋Š ์ชฝ์ด๋“  ๊ดœ์ฐฎ์ง€๋งŒ ๋•Œ๋•Œ๋กœ ์ด๊ฒƒ์€ ๋ฐฐํ„ฐ๋ฆฌ๊ฐ€ ํฌํ•จ๋œ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์ œ์™ธํ•˜๊ณ ๋Š” ๋งˆ์ง€๋ง‰ ์ž‘์—…์ธ Angular์— ๋ถ„๋ฆฌ๋œ ๋Š๋‚Œ์„ ์ฃผ๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.

๊ฐœ์ธ์ ์œผ๋กœ ๋ชจ๋“  Angular ํŒจํ‚ค์ง€(HTTP, Router, Forms)์— ๋Œ€ํ•ด ๋น„ RxJS ๋ฒ„์ „์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ด๊ฒƒ๋“ค์˜ ์ข‹์€ ๋น„ RxJS ๋ฒ„์ „์ด ์—†๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๊ทธ๋“ค์ด ์ฒ˜์Œ์— RxJS๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์ด์œ ์ž…๋‹ˆ๋‹ค.

์ฆ‰....๋‚ด๊ฐ€ ๋ญ”๊ฐ€๋ฅผ ๋†“์น˜๊ณ  ์žˆ์ง€ ์•Š๋Š” ํ•œ, (2)๋Š” ์‹คํ˜„ ๊ฐ€๋Šฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.


์ถ”์‹  ์ €๋Š” ์ด๋Ÿฌํ•œ ์š”์ฒญ์„ "์ง๊ต"๋ผ๊ณ  ์„ค๋ช…ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. "๋ฐ˜๋Œ€"์— ๋” ๊ฐ€๊น์Šต๋‹ˆ๋‹ค.

Angular์˜ RxJS๊ฐ€ ์ ์–ด ์ž ์žฌ์ ์œผ๋กœ ์„ ํƒ ์‚ฌํ•ญ์ด ๋ฉ๋‹ˆ๋‹ค.

@mgechev์— ๋Œ€ํ•œ ํ˜ธ๊ธฐ์‹ฌ์œผ๋กœ Github ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? (๋‚˜๋Š” ๋ณธ ์ ์ด ์—†์Šต๋‹ˆ๋‹ค.) ์•„๋‹ˆ๋ฉด ์ด๊ฒƒ์€ ๋” Google ์ง์›์˜ ๊ฒƒ์ž…๋‹ˆ๊นŒ?

@pauldraper github์—์„œ ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ rxjs๊ฐ€ ์–ผ๋งˆ๋‚˜ ๋”์ฐํ•˜๊ฒŒ ๋ณต์žกํ•œ์ง€์— ๋Œ€ํ•ด ๋ถˆํ‰ํ•˜๊ณ  ์™„์ „ํžˆ ์„ ํƒ ์‚ฌํ•ญ์ด ๋˜๊ธฐ๋ฅผ ์›ํ•˜๋Š” ๋ฌธ์ œ๋ฅผ ์ ์–ด๋„ ํ•˜๋‚˜๋Š” ๋ณด์•˜์Šต๋‹ˆ๋‹ค. ๊ฐœ์ธ์ ์œผ๋กœ ๋‚˜๋Š” rxjs๋ฅผ ์ข‹์•„ํ•˜์ง€๋งŒ ๋‘ ํŒ€๊ณผ ํ•จ๊ป˜ ์ผํ•˜๋ฉด์„œ ์ฃผ๋‹ˆ์–ด์™€ ์‹œ๋‹ˆ์–ด ๊ฐœ๋ฐœ์ž ๋ชจ๋‘์—๊ฒŒ ๋‘๋ ค์›€๊ณผ ํ˜์˜ค๊ฐ์„ ๋ถˆ๋Ÿฌ์ผ์œผ์ผฐ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์ง๊ต๋Š” ๋ฐ˜๋Œ€๋ณด๋‹ค ๋” ๋‚˜์€ ์šฉ์–ด์ž…๋‹ˆ๋‹ค. ๋‘ ์š”์ฒญ์„ ๋™์‹œ์— ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค(๊ฐ ์†”๋ฃจ์…˜์€ ๋ฐ˜์‘์ ์ด๊ณ  ๋ช…๋ น์ ์œผ๋กœ ์†Œ๋น„ํ•˜๋Š” ์—ฌ๋Ÿฌ API ์˜ต์…˜์„ ์ œ๊ณตํ•˜์—ฌ ๋‹ค๋ฅธ ์†”๋ฃจ์…˜์„ ๋ฐฉํ•ดํ•˜์ง€ ์•Š๊ณ  ์ž‘๋™ํ•  ์ˆ˜ ์žˆ์Œ).

github์˜ rxjs์— ๋Œ€ํ•ด ๋ถˆํ‰ํ•˜๋Š” ๋ชจ๋“  ๋Œ“๊ธ€์—๋Š” ์ˆ˜์ฒœ ๋ช…์˜ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋ฌธ์ œ ์—†์ด ์‚ฌ์šฉํ•˜๊ณ  ์ฆ๊ธฐ๊ณ  ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

image

image

๋‹ค์Œ ์€ Angular discord์—์„œ ํ† ๋ก ํ•˜๋ฉด์„œ ์œ„์— ๊ฒŒ์‹œํ•œ ์–‘์‹์˜ ๊ฒฐ๊ณผ์ž…๋‹ˆ๋‹ค(๊ฑฐ์˜ 200๋ช…์ด ์‘๋‹ตํ–ˆ์Šต๋‹ˆ๋‹ค).

๋‹น์—ฐํžˆ ํ˜•ํƒœ๊ฐ€ ๊ฐ€์žฅ ํฐ ๊ณจ์นซ๊ฑฐ๋ฆฌ ์ง€๋งŒ ๋ถ„๋ช…ํžˆ @MikeRyanDev ๊ฐ€ ๋งˆ์นจ๋‚ด ๋ฌด์–ธ๊ฐ€๋ฅผ ์š”๋ฆฌํ•˜๊ณ  ์žˆ์„์ง€๋„ ๋ชจ๋ฆ…๋‹ˆ๋‹ค .

github์˜ rxjs์— ๋Œ€ํ•ด ๋ถˆํ‰ํ•˜๋Š” ๋ชจ๋“  ๋Œ“๊ธ€์—๋Š” ์ˆ˜์ฒœ ๋ช…์˜ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋ฌธ์ œ ์—†์ด ์‚ฌ์šฉํ•˜๊ณ  ์ฆ๊ธฐ๊ณ  ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

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

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

๊ทธ๊ฒƒ๋“ค์€ ๊ฐœ๋ฐœ์ž Angular๊ฐ€ ๊ทธ ๋‹น์‹œ์— ์†Œ์ง„๋˜์–ด ๋ฐฐ์šฐ๊ณ  ์‹ถ์ง€๋„ ์•Š๊ณ  ์ถฉ์กฑ์‹œํ‚ค๋ ค๊ณ  ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๊นŒ? :) ๊ทธ๋ฆฌ๊ณ  ๋ˆ„๊ฐ€ ์–ด์จŒ๋“  ์ด ์‹œ์ ์—์„œ ๊ด€์‹ฌ์„ ๊ฐ–์Šต๋‹ˆ๋‹ค. Angular๋Š” ํ•œ๋™์•ˆ ์‚ฌ์šฉ๋˜์–ด ์™”์œผ๋ฉฐ ์•„๋ฌด๋ฐ๋„ ๊ฐ€์ง€ ์•Š์œผ๋ฉฐ ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ์ˆ˜๋ช… ์ฃผ๊ธฐ, ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ์ž…๋ ฅ, ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ์ด๋ฒคํŠธ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ๊ฒฌ์ธ๋ ฅ์„ ์ ˆ๋Œ€ ์žƒ์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ์„ธ ๊ฐ€์ง€ ์ž‘์€ ๊ฒƒ์„ ์ถ”๊ฐ€ํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ์‚ฌ๋žŒ๋“ค์€ ์ž ์‹œ ๋™์•ˆ ๋งŒ์กฑํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๊ฒŒ ๋‹ค์ž…๋‹ˆ๋‹ค(๊ทธ๋ฆฌ๊ณ  ๊ธฐ๋ณธ ํŒจํ‚ค์ง€๋ฅผ ์™„์„ฑํ•˜๋ ค๋ฉด https://indepth.dev/component-features-with-angular-ivy/๋ฅผ ๋”ฐ๋ผ๊ฐ€์‹ญ์‹œ์˜ค).

angular_rxjs

์ด๊ฒƒ์ด ๋ชจ๋“  ๊ฒƒ์„ ๋งํ•ด์ค๋‹ˆ๋‹ค. IMHO Angular๋Š” ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๊ณ  ๋” ๋งŽ์€ RxJS๋ฅผ ์‚ฌ์šฉํ•ด์•ผ

Angular๊ฐ€ ๊ทธ ๋•Œ ํ•ด๊ฒฐํ•˜๋ ค๊ณ  ํ•˜๋Š” ๊ฒƒ์ด ๋ฐ”๋กœ ๊ฐœ๋ฐœ์ž์ž…๋‹ˆ๊นŒ? :)

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

๋‹ค์‹œ ๋งํ•˜์ง€๋งŒ, ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ์ˆ˜๋ช… ์ฃผ๊ธฐ, ์ž…๋ ฅ, ์ด๋ฒคํŠธ๋ฅผ ์ถ”๊ฐ€ํ•  ๋•Œ์™€ ๊ฐ™์ด "์™„์ „ํžˆ ๋ฐ˜์‘์ "์œผ๋กœ ์ง„ํ–‰ํ•˜๋Š” ๊ฒƒ์€ ๋‹น์‹ ์ด ๋งํ•˜๋Š” ๊ฒƒ์— ์–ด๋–ค ์‹์œผ๋กœ๋“  ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š์ง€๋งŒ ๋‹ค๋ฅธ ๊ทธ๋ฃน์„ ๋งค์šฐ ํ–‰๋ณตํ•˜๊ฒŒ ๋งŒ๋“ค ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์ปดํฌ๋„ŒํŠธ ๊ธฐ๋Šฅ์€ ๋ฐ˜์‘ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์ข‹์•„ํ•˜๋“  ์ข‹์•„ํ•˜์ง€ ์•Š๋“  ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

@fxck ๋‚˜๋Š” ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ํ•œ ์ˆœ๊ฐ„๋„ ๋™์˜ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” rxjs๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ๋ฅผ ์›ํ•˜์ง€ ์•Š๋Š” ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด ์žˆ๊ณ  ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ๋ถˆํ‰ํ•˜๊ธฐ ์œ„ํ•ด github ๋ฌธ์ œ๋ฅผ ์—ด์—ˆ์Šต๋‹ˆ๋‹ค.

Angular๊ฐ€ ์ฝ”์–ด๋ฅผ ๊ฐœ๋ฐœํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ•œ ๋ฐฉ๋ฒ•(๋ฐ˜์‘์ ์ด๋“  ์•„๋‹ˆ๋“ )์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ์ด์ƒ์ ์ธ ์„ธ๊ณ„์—์„œ๋Š” ๋ฐ˜๋Œ€ ์š”๊ตฌ๋ฅผ ์ถฉ์กฑํ•˜๊ธฐ ์œ„ํ•ด ์œ„์— ๋นŒ๋“œ๋œ ๋ฐ˜๋Œ€ ํŒจํ‚ค์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค(์˜ˆ: @angular/reactive ๋˜๋Š” @angular/imperative - ๋” ๋‚˜์€ ์ด๋ฆ„์œผ๋กœ). ์ž˜ํ•˜๋ฉด).

์ปค๋ฎค๋‹ˆํ‹ฐ์— ๊ฐ€๋Š” ์ด ๋‘ ๊ฐ€์ง€ ์ค‘ ํ•˜๋‚˜๋Š” ์ €์—๊ฒŒ ์–ด๋–ค ์‚ฌ๋žŒ๋“ค์—๊ฒŒ๋Š” ๋‹ค์šด๊ทธ๋ ˆ์ด๋“œ์ด๋ฉฐ ์ €์—๊ฒŒ๋Š” ํ›Œ๋ฅญํ•œ ๋ฐ˜์‘ ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ๋  ๊ฒƒ์ด๋ผ๋Š” ๊ฐ๋„๊ฐ€ ์ฒ˜์Œ๋ถ€ํ„ฐ ํ•จ๊ป˜ ๊ฐ€์•ผ ํ•˜๋Š” ์ด์œ ์˜€์Šต๋‹ˆ๋‹ค.


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

๋ฉด์ฑ… ์กฐํ•ญ: ๊ฐ€์ •์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ณต์‹ํ™”ํ•œ ๋งˆ์ง€๋ง‰ ์š”์  - ํ•ต์‹ฌ ๋ช…๋ น์„ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด ํ›จ์”ฌ ๋” ์‰ฝ๋‹ค๋ฉด ๋†€๋ผ์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. - ํ™•์žฅ ๋ฐ˜์‘์€ ๋” ๋ณต์žกํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@mgechev์— ๋Œ€ํ•œ ํ˜ธ๊ธฐ์‹ฌ์œผ๋กœ Github ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? (๋‚˜๋Š” ๋ณธ ์ ์ด ์—†์Šต๋‹ˆ๋‹ค.) ์•„๋‹ˆ๋ฉด ์ด๊ฒƒ์€ ๋” Google ์ง์›์˜ ๊ฒƒ์ž…๋‹ˆ๊นŒ?

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

์šฐ๋ฆฌ๋Š” ์ˆ˜๋งŽ์€ ์™ธ๋ถ€ ํšŒ์‚ฌ, ๋‚ด๋ถ€ ํŒ€, ๊ฐœ์ธ ๊ธฐ์—ฌ์ž ๋“ฑ ์ˆ˜์ฒœ ๋ช…์˜ ๊ฐœ๋ฐœ์ž์™€ ์—ฐ๋ฝํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋‘ ๊ฒฝ์šฐ ๋ชจ๋‘ RxJS์— ์™„์ „ํžˆ ์ฐธ์—ฌํ•˜๊ณ  ์‹ถ์–ดํ•˜๋Š” ์‚ฌ๋žŒ๋“ค๊ณผ ๊ทธ๊ฒƒ์ด ๊ทธ๋“ค์—๊ฒŒ ์˜ฌ๋ฐ”๋ฅธ ์„ ํƒ์ด ์•„๋‹ˆ๋ผ๊ณ  ์ƒ๊ฐํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋‘ ์ง„์˜ ๋ชจ๋‘ ํ›Œ๋ฅญํ•œ ๋…ผ๊ฑฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ์šฐ๋ฆฌ๊ฐ€ ์„œ๋‘๋ฅด๊ณ  ์‹ถ์€ ๊ฒฐ์ •์ด ์•„๋‹™๋‹ˆ๋‹ค. ํŠนํžˆ ์ž˜ ์ •๋ฆฝ๋œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•/์ปค๋ฎค๋‹ˆํ‹ฐ ์†”๋ฃจ์…˜์ด ์žˆ๋Š” ๊ฒฝ์šฐ ์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ ์ˆ˜ํ–‰๋œ ์ž‘์—…์€ ์ถ”๊ฐ€ ๋ฐ์ดํ„ฐ ํฌ์ธํŠธ๋ฅผ ์ˆ˜์ง‘ํ•˜๊ณ  ํ˜„์žฌ ๋ณ€์ˆ˜ ์„ธํŠธ์— ๋Œ€ํ•œ ์ตœ์ ์˜ ์†”๋ฃจ์…˜์„ ์„ค์ •ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค.

Angular ์•ฑ์„ ๊ฐœ๋ฐœํ•  ๋•Œ ํ•˜๋‚˜์˜ ํ†ตํ•ฉ๋œ ์ ‘๊ทผ ๋ฐฉ์‹์„ ๋ฐ˜์‘ํ˜• ๋˜๋Š” ํ•„์ˆ˜(ํ”„๋กœ์ ํŠธ๋‹น ์„ ํƒ)๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋งค์šฐ ์œ ์šฉํ•  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ํ˜ผํ•ฉ ๋ฐ ์ผ์น˜ ๊ธฐ๋Šฅ์€ ๊ฐœ๋ฐœ ๊ฒฝํ—˜์„ ์ง€์›ํ•˜์ง€ ์•Š์œผ๋ฉฐ ๋น„ DRY ์ฝ”๋“œ(์˜ˆ: ๋น„๋ฐ˜์‘์  ์ž…๋ ฅ)๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

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

์ฆ‰, ๋‚ด๊ฐ€ ํ˜„์‹ค์ ์ด์ง€ ์•Š๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋Š” ๊ฒƒ์€ ๋ช…๋ นํ˜• ์ธํ„ฐํŽ˜์ด์Šค ์œ„์— ๋ฐ˜์‘ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๋ฐฉํ–ฅ์€ ๊ด€์ฐฐ ๊ฐ€๋Šฅ ํ•ญ๋ชฉ์˜ ์ถœ๋ ฅ์„ ํ•ญ์ƒ ๋ณ€์ˆ˜์— ์“ธ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋งค์šฐ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. ๋ณ€์ˆ˜๋Š” ๋ช…๋ น์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์‹ค ์ด๊ฒƒ์ด Angular๊ฐ€ ์ด๋ฏธ ๋งŽ์€ ๊ณณ์—์„œ ํ•˜๊ณ  ์žˆ๋Š” ์ผ์ž…๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ๋‚˜๋Š” Angular๋ฅผ ํ•ต์‹ฌ์—์„œ ์™„์ „ํžˆ ๋ฐ˜์‘ํ•˜๋„๋ก ๋งŒ๋“  ๋‹ค์Œ ๋งจ ์œ„์— ๋ช…๋ นํ˜• "๋ž˜ํผ"๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐ ํˆฌํ‘œํ•ฉ๋‹ˆ๋‹ค.

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

@mgechev ์ด๊ฒƒ์€ ๋ช‡ ๋ฒˆ์ด๋‚˜ ์ œ๊ธฐ๋˜์—ˆ์œผ๋ฏ€๋กœ ๋ฐ˜์‘์„ฑ ์ฝ”์–ด/๋ช…๋ นํ˜• ํ™•์žฅ์— ๋Œ€ํ•œ ๊ท€ํ•˜์˜ ์ƒ๊ฐ๊ณผ ์„ค ์ˆ˜ ์žˆ๋Š” ๋‹ค๋ฆฌ๊ฐ€ ์žˆ๋Š”์ง€ ๋“ฃ๋Š” ๊ฒƒ์ด ํฅ๋ฏธ๋กœ์šธ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‘ ๊ฒฝ์šฐ ๋ชจ๋‘ RxJS์— ์™„์ „ํžˆ ์ฐธ์—ฌํ•˜๊ณ  ์‹ถ์–ดํ•˜๋Š” ์‚ฌ๋žŒ๋“ค๊ณผ ๊ทธ๊ฒƒ์ด ๊ทธ๋“ค์—๊ฒŒ ์˜ฌ๋ฐ”๋ฅธ ์„ ํƒ์ด ์•„๋‹ˆ๋ผ๊ณ  ์ƒ๊ฐํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋‘ ์ง„์˜ ๋ชจ๋‘ ํ›Œ๋ฅญํ•œ ๋…ผ๊ฑฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ข‹์Šต๋‹ˆ๋‹ค. RxJS๋กœ ๋ณธ๊ฒฉ์ ์ธ ์ž‘์—…์„ ์ •์˜ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ์ˆ˜๋ช… ์ฃผ๊ธฐ, ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ์ž…๋ ฅ ๋ฐ ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ์ด๋ฒคํŠธ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ๊ทธ๋ฆฌ๊ณ  ์•„๋‹ˆ์š”, ์ด๋“ค ์ค‘ ์–ด๋Š ๊ฒƒ๋„ ์‹ค์ œ๋กœ "์ž˜ ํ™•๋ฆฝ๋œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•/์ปค๋ฎค๋‹ˆํ‹ฐ ์†”๋ฃจ์…˜"์ด ์—†์Šต๋‹ˆ๋‹ค.

@fxck ์ด๋“ค ์ค‘ ์–ด๋Š ๊ฒƒ๋„ ์‹ค์ œ๋กœ "์ž˜ ํ™•๋ฆฝ๋œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•/์ปค๋ฎค๋‹ˆํ‹ฐ ์†”๋ฃจ์…˜"์ด ์—†์Šต๋‹ˆ๋‹ค.

๏ฟผ์‚ฌ์‹ค์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ด๋Ÿฌํ•œ ์†”๋ฃจ์…˜ ์ค‘ ํ•˜๋‚˜๋ฅผ ์ž‘์„ฑํ–ˆ์œผ๋ฉฐ ํ…œํ”Œ๋ฆฟ์˜ ์ž˜๋ชป๋œ ์œ ํ˜• ๊ฒ€์‚ฌ์— ์˜์กดํ•˜๋Š” ํ•˜๋‚˜์˜ ํฐ ํ•ดํ‚น์œผ๋กœ ์ธํ•ด์„œ๋งŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ์ด ์Šค๋ ˆ๋“œ์— ๊ฒŒ์‹œ๋œ ๋ช‡ ๊ฐ€์ง€ ๋‹ค๋ฅธ ์†”๋ฃจ์…˜๋„ ํ™•์ธํ–ˆ์œผ๋ฉฐ ๊ฐ๊ฐ์—๋Š” ๋‹ค์Œ ๋ฌธ์ œ ์ค‘ ํ•˜๋‚˜ ์ด์ƒ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๊ตฌ๋… ๋ˆ„์ถœ
  • ์‚ฌ์šฉ์ž์— ๋Œ€ํ•œ ์ƒ์šฉ๊ตฌ ์š”๊ตฌ ์‚ฌํ•ญ
  • ๋‚ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์‚ฌ์šฉํ•œ ๊ฒƒ๋ณด๋‹ค ๋‚˜์˜์ง€๋Š” ์•Š์ง€๋งŒ ๋‚˜์˜์ง€ ์•Š์€ ํ•ดํ‚น์ž…๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ์ƒ๊ฐํ•˜๋Š” ํ•œ, ์ด๊ฒƒ์„ ๋ฉ‹์ง€๊ฒŒ ํ•˜๋Š” ๊ฒƒ์€ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ์ด๋ฒคํŠธ๋Š” ํ›จ์”ฌ ๋” ๋‚˜์ฉ๋‹ˆ๋‹ค. ์ปค๋ฎค๋‹ˆํ‹ฐ ์†”๋ฃจ์…˜์ด ๋งŽ์ง€ ์•Š์œผ๋ฉฐ ์ผ๋ฐ˜์ ์œผ๋กœ ์ถ”๊ฐ€ ๋นŒ๋“œ ๋‹จ๊ณ„(์ผ๋ถ€ ๊ฒฝ์šฐ monorepo ์„ค์ •์—์„œ SSR ์ค‘๋‹จ)์™€ ๊ทธ ์œ„์— ํ•ดํ‚น์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค(์˜ˆ๋ฅผ ๋“ค์–ด ํด๋ž˜์Šค ํ™•์žฅ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ). Angular๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์ด๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์ˆ˜๋ช… ์ฃผ๊ธฐ ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ์ด๋ฒคํŠธ๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. https://github.com/typebytes/ngx-template-streams/issues/8

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

@fxck ๋‚ด๊ฐ€ ์•„๋Š” ํ•œ ๋ถ€๋ชจ ํด๋ž˜์Šค(eug) ๋˜๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์ž์ฒด ํŒŒ๊ดด ์ˆ˜๋ช… ์ฃผ๊ธฐ ์ด๋ฒคํŠธ(๋” ๋‚˜์œ ๊ฒฝ์šฐ)์—์„œ ํ˜ธ์ถœํ•ด์•ผ ํ•˜๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ์ˆ˜๋ช… ์ฃผ๊ธฐ ์ด๋ฒคํŠธ ๊ตฌ๋…์„ ์ •๋ฆฌํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

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

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

@tonivj5 ๊ตฌ์„ฑ ์š”์†Œ ๊ธฐ๋Šฅ ์ด ๊ณต๊ฐœ API์ธ ๊ฒฝ์šฐ ์ƒ์† ์—†์ด ์ˆ˜๋ช… ์ฃผ๊ธฐ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ์ž ์žฌ์ ์ธ ๋ฐฉ๋ฒ•์ด๋ผ๊ณ  ๋ณด์‹ญ๋‹ˆ๊นŒ ?

@ntziolis ํ•˜ํ•˜ ๊ธฐ๋Šฅ์„ ์–ธ๊ธ‰ํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ์ด ์žฌ๋ฏธ์žˆ์Šต๋‹ˆ๋‹ค. ์ €๋Š” ์‹ค์ œ๋กœ ngx-sub-form์˜ ์ˆ˜๋ช… ์ฃผ๊ธฐ ๋ถ€๋ถ„์—์„œ ์ž‘์—…ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ๊ธฐ๋Šฅ์€ ์ •ํ™•ํžˆ ์ œ๊ฐ€ ๋„์›€์ด ๋  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ ๋™์•ˆ ์•„์ด๋น„๋กœ ๊ตฌ์„ฑ ์š”์†Œ ๊ณต์žฅ์„ ํŒจ์น˜ํ•˜๋Š” ๊ฒƒ์€ ๋งค์šฐ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ด๊ฒƒ์ด ngx-sub-form ์™ธ๋ถ€์—์„œ ๋งค์šฐ ์œ ์šฉํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฏ€๋กœ ์ด ๋…ผ๋ฆฌ๋ฅผ ๋ณ„๋„์˜ lib๋กœ ๋ถ„ํ• ํ•  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

@ntziolis ์ด ์‹œ์ ์—์„œ Ivy ์•ฝ์†์ด ์‹ค์ œ๋กœ ์ „๋‹ฌ๋˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์„์ง€ ํ™•์‹ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๊ฐ์ง„ ํšจ๊ณผ๋ฅผ ํ™•์ธ ํ–ˆ์Šต๋‹ˆ๊นŒ? (ngrx/effects ์•„๋‹˜) https://dev.to/stupidawesome/reactive-adventures-in-angular-introducing-angular-effects-1epf ์ด ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์™„์ „ํžˆ ๋ฐ˜์‘ํ•˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋ถ€๋ชจ ๋ฐ ์ž์‹ ๊ตฌ์„ฑ ์š”์†Œ ๊ฐ„์˜ ์–‘๋ฐฉํ–ฅ ๊ด€์ฐฐ ๊ฐ€๋Šฅ ์ƒํƒœ ํฌํ•จ
https://dev.to/stupidawesome/exploring-the-angular-effects-api-2gol
๋ฒ„์ „ 9.1.0์€ Vue 3์˜ ๊ตฌ์„ฑ API๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋Š” ๊ตฌ์„ฑ/ํ›„ํฌ ๋ชจ๋ธ์„ ๋„์ž…ํ•ฉ๋‹ˆ๋‹ค.
Angular๊ฐ€ ๋ฐ˜์‘์„ฑ๊ณผ ํ•จ๊ป˜ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ์€ ์ •๋ง ๋‹ค์Œ ๋‹จ๊ณ„๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

@mgechev

์ด๊ฒƒ์€ ํŠนํžˆ ์ž˜ ํ™•๋ฆฝ๋œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•/์ปค๋ฎค๋‹ˆํ‹ฐ ์†”๋ฃจ์…˜์ด ์žˆ๋‹ค๋Š” ์ ์„ ๊ณ ๋ คํ•  ๋•Œ ์„œ๋‘๋ฅด๊ณ  ์‹ถ์€ ๊ฒฐ์ •์ด ์•„๋‹™๋‹ˆ๋‹ค.

๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋ˆ„๊ตฌ์ด๋ฉฐ ์–ผ๋งˆ๋‚˜ ๋งŽ์€ Google ์ง์›์ด Angular ์˜์‚ฌ ๊ฒฐ์ • ๊ณผ์ •์— ์ ๊ทน์ ์œผ๋กœ ๊ธฐ์—ฌํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?

๋‹น์‹ ์€ ์ด๊ฒƒ์ด ์„œ๋‘๋ฅด์ง€ ๋ง์•„์•ผ ํ•  ๊ฒฐ์ •์ด ์•„๋‹ˆ๋ผ๊ณ  ๋งํ–ˆ์ง€๋งŒ, ์„œ๋‘๋ฅด์ง€ ์•Š๋Š”๋‹ค๋Š” ๋‹น์‹ ์˜ ์ •์˜๊ฐ€ ๋ฌด์—‡์ธ์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ 'Fixed by Ivy' ํƒœ๊ทธ๋ฅผ ๋•Œ๋ฆฌ๊ณ  ๋” ๋งŽ์€ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ƒํ™ฉ์„ ๋‹ค์‹œ ์‹œ๋„๋Ÿฝ๊ฒŒ ๋งŒ๋“ค๊ธฐ ์‹œ์ž‘ํ•  ๋•Œ๊นŒ์ง€ ๋ฌด์‹œํ•˜๋Š” ๊ฒƒ ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๊นŒ? ๋ฐ˜์‘ ์ž‘์—…์— ๋Œ€ํ•ด ์—ผ๋‘์— ๋‘” ๋Œ€์ƒ ๋ฒ„์ „์ด ์žˆ์Šต๋‹ˆ๊นŒ? ์•„๋‹ˆ๋ฉด ๋จผ์ € ๋ฆด๋ฆฌ์Šคํ•ด์•ผ ํ•˜๋Š” ๋‹ค๋ฅธ ์ตœ์‹  ์ปดํŒŒ์ผ๋Ÿฌ ๋ฒ„์ „์ด ์žˆ์Šต๋‹ˆ๊นŒ?

์ฃผ์–ด์ง„ ์‹œ๊ฐ„์— ์ผ๋ฐ˜์ ์œผ๋กœ 2500๊ฐœ์˜ ๋ฏธํ•ด๊ฒฐ ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค๋Š” ์‚ฌ์‹ค์ด ๋‚ด๋ถ€ ํ† ๋ก ์—์„œ ๋‚˜์˜จ ์ ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

@ntziolis , @zakhenry๊ฐ€ ๋งํ–ˆ๋“ฏ์ด features ๊ฐ€ ๋„์›€์ด ๋  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

@ntziolis ๋‚˜๋Š” ์ˆ˜๋ช… ์ฃผ๊ธฐ์— ๋Œ€ํ•ด ๋‹ค๋ฅธ ์‹œ๋„๋ฅผ ํ–ˆ๊ณ  ์ž‘๋™ํ•˜๋Š” POC๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค (ํด๋ž˜์Šค ํ™•์žฅ์ด ์—†๊ณ  ์ˆ˜๋ช… ์ฃผ๊ธฐ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์Œ). ํ”„๋ผ์ด๋น— API์— ์˜์กดํ•ฉ๋‹ˆ๋‹ค(:exclamation:)

@tonivj5 ํ•˜ํ•˜ ๋‹น์‹ ์˜ ๊ธ€์„ ์ฝ์„ ๊ธฐํšŒ๊ฐ€ ์—†์—ˆ์ง€๋งŒ ์ œ ์†”๋ฃจ์…˜๋„ ๊ฑฐ์˜ ์ถœ์‹œ๋  ๋ป”ํ–ˆ์Šต๋‹ˆ๋‹ค :) https://github.com/cloudnc/ngx-observable-lifecycle

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

CI์™€ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ์ •๋ ฌํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

์ฃผ์–ด์ง„ ์‹œ๊ฐ„์— ์ผ๋ฐ˜์ ์œผ๋กœ 2500๊ฐœ์˜ ๋ฏธํ•ด๊ฒฐ ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค๋Š” ์‚ฌ์‹ค์ด ๋‚ด๋ถ€ ํ† ๋ก ์—์„œ ๋‚˜์˜จ ์ ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

Lol, 2019๋…„ ์ค‘๋ฐ˜ ์ดํ›„๋กœ 2500๊ฐœ์˜ ๊ณต๊ฐœ ๋ฌธ์ œ๊ฐ€ ์—†์—ˆ์Šต๋‹ˆ๋‹ค.

$ github_issue_stats history -i2m -n20 -sangular/angular

+-------------------------+--------------------+
|         period          |       issues       |
+-------------------------+--------------------+
| This month (2020-05)    | 2855 (+137, -112)  |
| Last month (2020-03)    | 2830 (+495, -550)  |
| 2 months ago (2020-01)  | 2885 (+601, -575)  |
| 3 months ago (2019-11)  | 2859 (+437, -352)  |
| 4 months ago (2019-09)  | 2774 (+411, -305)  |
| 5 months ago (2019-07)  | 2668 (+441, -369)  |
| 6 months ago (2019-05)  | 2596 (+488, -349)  |
| 7 months ago (2019-03)  | 2457 (+425, -373)  |
| 8 months ago (2019-01)  | 2405 (+428, -330)  |
| 9 months ago (2018-11)  | 2307 (+425, -391)  |
| 10 months ago (2018-09) | 2273 (+515, -466)  |
| 11 months ago (2018-07) | 2224 (+641, -541)  |
| 12 months ago (2018-05) | 2124 (+690, -624)  |
| 13 months ago (2018-03) | 2058 (+605, -444)  |
| 14 months ago (2018-01) | 1897 (+773, -679)  |
| 15 months ago (2017-11) | 1803 (+815, -979)  |
| 16 months ago (2017-09) | 1967 (+671, -431)  |
| 17 months ago (2017-07) | 1727 (+664, -518)  |
| 18 months ago (2017-05) | 1581 (+854, -548)  |
| 19 months ago (2017-03) | 1275 (+987, -796)  |
| 20 months ago (2017-01) | 1084 (+671, -505)  |
+-------------------------+--------------------+

๋‚ด ์ทจํ–ฅ์— ๋”ฐ๋ผ ํ† ๋ก  ์—†์ด ์—ด๋ฆฐ ๊ฐ ๋ฌธ์ œ๋ฅผ ๋‹ซ๋Š” ํ”„๋กœ์ ํŠธ๋ณด๋‹ค ๋ช…ํ™•ํ•œ ์ปค๋ฎค๋‹ˆํ‹ฐ ํ† ๋ก /ํ•ฉ์˜๊ฐ€ ์žˆ์„ ๋•Œ๊นŒ์ง€ ๋ฌธ์ œ๋ฅผ ํ† ๋ก ์— ๊ณต๊ฐœํ•˜๋Š” ์˜คํ”ˆ ์†Œ์Šค ํ”„๋กœ์ ํŠธ๋ฅผ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ์œ ์ง€ ๊ด€๋ฆฌ์ž๊ฐ€ ์ œ์•ˆ ์ˆ˜๋ฝ ๊ฐ€๋Šฅ์„ฑ์„ ์ฐจ๋‹จํ•˜๊ธฐ ์ „์— ์ปค๋ฎค๋‹ˆํ‹ฐ์— ์‹œ๊ฐ„์ด ์ง€๋‚จ์— ๋”ฐ๋ผ ์šฐ๋ ค ์‚ฌํ•ญ์„ ์„ค๋ช…ํ•˜๋Š” ๋‹จ๊ณ„์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.

@agalazis ์ด ๋ฌธ์ œ๋Š” 4 1/2๋…„ ๋™์•ˆ ๊ณต๊ฐœ๋˜์—ˆ์œผ๋ฉฐ ์ง€๋‚œ 3๋…„ ๋™์•ˆ ๊ฑฐ์˜ ๋ฌด์‹œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

@agalazis ์ด ๋ฌธ์ œ๋Š” 4 1/2๋…„ ๋™์•ˆ ๊ณต๊ฐœ๋˜์—ˆ์œผ๋ฉฐ ์ง€๋‚œ 3๋…„ ๋™์•ˆ ๊ฑฐ์˜ ๋ฌด์‹œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

Angular ํŒ€ ๊ตฌ์„ฑ์›์ด ์™œ ์ด๊ฒƒ์ด ์•„์ง 5์ผ ์ „์— ์—ด๋ ค ์žˆ๋Š”์ง€ ์„ค๋ช…ํ•˜๋ฏ€๋กœ ๋‹น์‹ ์ด ์˜ณ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

@etay2000 ์–ด๋–ค ๊ฒฐ์ •์€ ์ „์ฒด ํ”„๋กœ์ ํŠธ์˜ ๋ฐœ์ „์— ์˜ํ–ฅ์„ ๋ฏธ์น˜๊ธฐ ๋•Œ๋ฌธ์— ๋•Œ๋•Œ๋กœ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ์ˆ˜์šฉ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž๋Š” ์‹œ๊ฐ„์ด ์ง€๋‚จ์— ๋”ฐ๋ผ ๊ฐ€๊นŒ์šด ์žฅ๋ž˜์— ๊ธฐ๋Šฅ์— ์˜์กดํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์„ ๊นจ๋‹ฌ์„ ์ˆ˜ ์žˆ์ง€๋งŒ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋‹ค๋ฉด ์™œ ์กฐ๊ธฐ์— ์ข…๋ฃŒํ•ฉ๋‹ˆ๊นŒ? ๊ฐ€์žฅ ์‰ฌ์šด ๋ฐฉ๋ฒ•์€ ์ œ์•ˆ์„ ๊ฑฐ๋ถ€ํ•˜๊ณ  ๋ฌธ์ œ๋ฅผ ์ข…๋ฃŒํ•˜๋Š” ๊ฒƒ์ด์ง€๋งŒ ์ด์œ ๊ฐ€ ์žˆ์–ด์„œ ๋ฐœ์ƒํ•˜์ง€ ์•Š์•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

@beeman

Angular ํŒ€ ๊ตฌ์„ฑ์›์ด ์™œ ์ด๊ฒƒ์ด ์•„์ง 5์ผ ์ „์— ์—ด๋ ค ์žˆ๋Š”์ง€ ์„ค๋ช…ํ•˜๋ฏ€๋กœ ๋‹น์‹ ์ด ์˜ณ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์—„์ง€์†๊ฐ€๋ฝ์„ ์•„๋ž˜๋กœ ๋‚ด๋ฆฌ๋Š” ์ด๋ชจํ‹ฐ์ฝ˜์ด ์ •๋ง ๋งˆ์Œ์— ๋“œ์‹œ๋‚˜์š”? ๊ทธ๋Ÿฐ๋ฐ ๊ทธ๊ฒŒ ์ •๋ง ์„ค๋ช…์ด ๋˜์—ˆ๋‚˜์š”? 4๋…„์ด ์ง€๋‚œ ํ›„ ๊ทธ๋Š” ๊ฒฐ์ •์„ ์„œ๋‘๋ฅด๊ณ  ์‹ถ์ง€ ์•Š๋‹ค๊ณ  ๋งํ–ˆ์Šต๋‹ˆ๋‹ค.

@agalazis
์ผ๋ถ€ ๊ฒฐ์ •์ด ์–ด๋ ต๋‹ค๋Š” ์ ์—๋Š” ๋™์˜ํ•˜์ง€๋งŒ ์–ด๋ ค์šด ๊ฒฐ์ •์„ ๋‚ด๋ฆฌ๋Š” ๊ฒƒ์„ ์—ฐ๊ธฐํ•  ์ˆ˜ ์žˆ๋Š” ํ—ˆ์šฉ ๊ฐ€๋Šฅํ•œ ์‹œ๊ฐ„ ํ”„๋ ˆ์ž„์œผ๋กœ ๊ฐ„์ฃผ๋˜์–ด์•ผ ํ•˜๋Š” ๊ฒƒ์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? 2855๊ฐœ์˜ ๋ชจ๋“  ๋ฏธํ•ด๊ฒฐ ๋ฌธ์ œ๊ฐ€ ์ด๋Ÿฌํ•œ ์–ด๋ ค์šด ๊ฒฐ์ •์„ ํฌํ•จํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ์ง€๋งŒ ๋งŽ์€ ๋ฌธ์ œ๋„ ๊ฝค ์˜ค๋žซ๋™์•ˆ ์กด์žฌํ•ด ์™”์Šต๋‹ˆ๋‹ค.

@etay2000 ์ˆ˜๋ฝ ์—ฌ๋ถ€๋Š” ์˜คํ”ˆ ์†Œ์Šค์ž…๋‹ˆ๋‹ค. ๋ฌธ์ œ๋ฅผ ์—ฌ๋Š” ์‚ฌ๋žŒ๋“ค์€ ์œ ์ง€ ๊ด€๋ฆฌ์ž๋ณด๋‹ค ํ›จ์”ฌ ๋งŽ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด Typescript ํ”„๋กœ์ ํŠธ์—๋Š” ๊ฑฐ์˜ ๋‘ ๋ฐฐ๋‚˜ ๋งŽ์€ ๋ฌธ์ œ๊ฐ€ ์žˆ์œผ๋ฉฐ ๋‚ด๊ฐ€ ๊ฑฐ๊ธฐ์—์„œ ํ•œ ๋‹ค๋ฅธ ์ œ์•ˆ๋„ ์˜ค๋žœ ์‹œ๊ฐ„์ด ๊ฑธ๋ ธ์Šต๋‹ˆ๋‹ค. ํ† ๋ก ์—์„œ ๊ธฐ๋Šฅ์ด ์žˆ๋Š” ๊ฒƒ๋งŒํผ ํ™”๋ คํ•˜์ง€๋Š” ์•Š์ง€๋งŒ ๋‹ค๋ฅธ ๋งŽ์€ ๊ด€์ ์„ ๋ณผ ์ˆ˜ ์žˆ์—ˆ๋˜ ๋งŽ์€ ๋Œ€์•ˆ์ด ๋‚˜์™”๊ธฐ ๋•Œ๋ฌธ์— ์‹ ๊ฒฝ ์“ฐ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

@agalazis ๋„ค ๋ง์ด ๋งž์•„. ๋‚ด๊ฐ€ (์ž˜๋ชป๋œ) ์ž‘์€ ํ”„๋กœ์ ํŠธ์—์„œ๋ณด๋‹ค Google์—์„œ ์œ ์ง€ ๊ด€๋ฆฌํ•˜๋Š” ์˜คํ”ˆ ์†Œ์Šค ํ”„๋กœ์ ํŠธ์—์„œ ๋” ๋งŽ์€ ๊ฒƒ์„ ๊ธฐ๋Œ€ํ–ˆ๋˜ ๊ฒƒ ๊ฐ™๋‹ค.

@beeman ์—„์ง€์†๊ฐ€๋ฝ ์•„๋ž˜ ์ด๋ชจํ‹ฐ์ฝ˜์„ ์—ฌ๊ธฐ์— ์‚ฝ์ž…ํ•˜์‹ญ์‹œ์˜ค: -------->

@etay2000 ์ค‘์š”ํ•œ ๊ฒฐ์ • ํ•˜๋‚˜ํ•˜๋‚˜๊ฐ€ ์ˆ˜์‹ญ๋งŒ ๊ฐ€์ง€, ํ”„๋กœ์ ํŠธ, ์‚ฌ๋žŒ์—๊ฒŒ ์˜ํ–ฅ์„ ๋ฏธ์นœ๋‹ค๋Š” ์‚ฌ์‹ค์„ ํ•ญ์ƒ ๊ธฐ์–ตํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋” ์ค‘์š”ํ•œ ๊ฒƒ์€ ์™„๋ฒฝํ•˜์ง€ ์•Š์€ ๊ฒฐ์ •๊ณผ ๊ณต๊ฐœ API๋ฅผ ๋„์ž…ํ•œ ํ›„ ์งง์€ ์‹œ๊ฐ„์— ์ผ๋ถ€ ํš๊ธฐ์ ์ธ ๋ณ€๊ฒฝ์œผ๋กœ ์ด์–ด์งˆ ์•…๋ชฝ์ž…๋‹ˆ๋‹ค. ๊ฐ PR์—์„œ ๊ฐ ๋‹จ๊ณ„๊ฐ€ ์–ด๋–ป๊ฒŒ ๊ฒ€ํ† ๋˜๋Š”์ง€ ๊ฑฐ์˜ ๋ณผ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์™„๋ฒฝํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ๋ช‡ ์ฃผ, ๋ช‡ ๋‹ฌ ๋˜๋Š” ๋ช‡ ๋…„์„ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค.

@agalazis ๋„ค ๋ง์ด ๋งž์•„. ๋‚ด๊ฐ€ (์ž˜๋ชป๋œ) ์ž‘์€ ํ”„๋กœ์ ํŠธ์—์„œ๋ณด๋‹ค Google์—์„œ ์œ ์ง€ ๊ด€๋ฆฌํ•˜๋Š” ์˜คํ”ˆ ์†Œ์Šค ํ”„๋กœ์ ํŠธ์—์„œ ๋” ๋งŽ์€ ๊ฒƒ์„ ๊ธฐ๋Œ€ํ–ˆ๋˜ ๊ฒƒ ๊ฐ™๋‹ค.

๋ชจ๋ฅด๊ฒ ์–ด ๋ฐ”๋‘‘๋„ ๋‹คํŠธ๋„ ๋ด. Google์€ ์‹ค์ œ๋กœ 50๋…„ ๋™์•ˆ ์—„์ฒญ๋‚˜๊ฒŒ ์ธ๊ธฐ ์žˆ๋Š” ์ปค๋ฎค๋‹ˆํ‹ฐ ์š”์ฒญ์„ ๋ฌด์‹œํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๊ฝค ์œ ๋ช…ํ•ฉ๋‹ˆ๋‹ค. D ์ผ๋ฐ˜์ ์œผ๋กœ ์–ธ์–ด/ํ”„๋ ˆ์ž„์›Œํฌ ๋“ฑ์— ๋Œ€ํ•œ ์ ‘๊ทผ ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. ๋งค์šฐ ๋ณด์ˆ˜์  ์ž…๋‹ˆ๋‹ค. ์˜์—ญ์— ํ˜๋ช…์„ ์ผ์œผํ‚ค๊ณ  Google์—์„œ ๋ช‡ ๋…„ ๋™์•ˆ ์ด๋ฅผ ์ฑ„ํƒํ•˜์ง€ ์•Š๊ณ  ์žˆ๋Š” ์ƒˆ๋กœ์šด ์–ธ์–ด์™€ ์•„์ด๋””์–ด๊ฐ€ ๋“ฑ์žฅํ•˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด Dart๋ณด๋‹ค ์˜ค๋ž˜ ์ „์— null ์•ˆ์ „ ํžˆํŠธ Kotlin, TypeScript ๋ฐ Scala๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์ข…๋ฅ˜์˜ ์ ‘๊ทผ ๋ฐฉ์‹์—๋Š” ์žฅ์ ๊ณผ ๋‹จ์ ์ด ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€๋งŒ ์ ์–ด๋„ ์ €์—๊ฒŒ๋Š” Google์—์„œ ๊ฐœ๋ฐœํ•œ ๊ฒƒ์ด ์ œ ์ •์‹ ์— ๋งž์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ€๋Šฅํ•œ ํ•œ ํ”ผํ•˜๋Š” ๊ฒฝํ–ฅ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

(์—ฌ๋Ÿฌ๋ถ„ ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค๋งŒ ์ €๋Š” ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.)

@beeman ์—„์ง€์†๊ฐ€๋ฝ ์•„๋ž˜ ์ด๋ชจํ‹ฐ์ฝ˜์„ ์—ฌ๊ธฐ์— ์‚ฝ์ž…ํ•˜์‹ญ์‹œ์˜ค: -------->

@etay2000 ์ด๋Ÿฐ ์ข…๋ฅ˜์˜ ๋Œ“๊ธ€์ด ์—ฌ๊ธฐ์˜ ํ–‰์œ„ ์œ„๋ฐ˜์ด ์•„๋‹ˆ๋ผ๋ฉด ์–ด๋–ป๊ฒŒ ๋„์›€์ด ๋˜๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋ชจ๋‘๊ฐ€ ์–ด๋–ป๊ฒŒ ์—„์ง€์†๊ฐ€๋ฝ์„ ์น˜์ผœ๋“œ๋Š”์ง€ ์•Œ๊ณ  ์žˆ๋‹ค๊ณ  ํ™•์‹ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ํ’์ž์˜ ์š”์ ์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

๋‹ค์‹œ ๋งํ•˜์ง€๋งŒ, ์•„๋ฌด๋„ Angular๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ๊ฐ•์š”๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์‚ฌ๋žŒ๋“ค์ด ๋‹น์‹ ์„ ๋” ๊ธฐ์˜๊ฒŒ ํ•˜๋Š” ๋‹ค๋ฅธ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์ฐพ์œผ๋ ค๊ณ  ๋…ธ๋ ฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@brunojcm ๋Œ“๊ธ€ ๊ฒฝ์ฐฐ์ด ๋๋‚œ ๊ฒƒ ๊ฐ™์•„์š”. ์š”์ ์€ ๊ทธ๊ฐ€ ๋‚ด ๋‹ค๋ฅธ ๋ชจ๋“  ์˜๊ฒฌ์„ ๋ฌด์‹œํ–ˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‚˜๋Š” ํ’์ž๊ฐ€ ํ–‰๋™์„ ์œ„๋ฐ˜ํ•˜๋Š” ๊ฒƒ์ž„์„ ๊นจ๋‹ซ์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์‹œ ๋งํ•˜์ง€๋งŒ, ์•„๋ฌด๋„ Angular๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ๊ฐ•์š”๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์‚ฌ๋žŒ๋“ค์ด ๋‹น์‹ ์„ ๋” ๊ธฐ์˜๊ฒŒ ํ•˜๋Š” ๋‹ค๋ฅธ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์ฐพ์œผ๋ ค๊ณ  ๋…ธ๋ ฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ์ •๋ง๋กœ ๊ทธ๊ฒƒ์— ๋Œ€์‘ํ•˜๊ณ  ์‹ถ์€ ๋ฐฉ์‹์€ ๋ถ„๋ช…ํžˆ ์—ฌ๊ธฐ์— ์žˆ๋Š” ํ–‰๋™ ๊ฐ•๋ น์„ ์œ„๋ฐ˜ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋๋‚ฌ์Šต๋‹ˆ๋‹ค. ๋ชจ๋‘๊ฐ€ ์ •๊ธฐ์ ์œผ๋กœ ์˜ˆ์ •๋œ ํ”„๋กœ๊ทธ๋žจ์œผ๋กœ ๋Œ์•„๊ฐˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 4~5๋…„ ํ›„์— ์ƒํ™ฉ์ด ์–ด๋–ป๊ฒŒ ๋˜์—ˆ๋Š”์ง€ ๋‹ค์‹œ ํ™•์ธํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

@tonivj5 @zakhenry ์ด๊ฒƒ์ด ๊ธธ์ด ๋  ์ˆ˜ ์žˆ๋‹ค๋Š” ์†Œ์‹์„ ๋“ค์œผ๋‹ˆ ๋ฐ˜๊ฐ‘ ์Šต๋‹ˆ๋‹ค .

@mgchev ๋‚˜๋Š” ์ด๊ฒƒ์ด ์˜ˆ๋น„ ํ† ๋ก ์ด

  • ๋ฐ˜์‘ ์ฝ”์–ด + ๋น„ ๋ฐ˜์‘ ํ™•์žฅ ๋Œ€ ๋ฐ˜๋Œ€.
  • ์ด ๋ฌธ์ œ์— ๋Œ€ํ•ด ๋” ๊ตฌ์ฒด์ ์œผ๋กœ ๋งํ•˜๋ฉด ์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ๋“  ๊ธฐ๋Šฅ API๋ฅผ ๋…ธ์ถœํ•  ํ˜„์‹ค์ ์ธ ๊ธฐํšŒ๊ฐ€ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

    • ์ผ๋ฐ˜ ๊ธฐ๋Šฅ์— ์—ฌ์ „ํžˆ ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ๋Š” ํ•œ ํ–ฅํ›„ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ค‘๋‹จํ•œ๋‹ค๋Š” ๊ฒฝ๊ณ ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ์—๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค.

    • @zakhenry ๊ฐ€ ์ˆ˜๋ช… ์ฃผ๊ธฐ ์ด๋ฒคํŠธ์— ๋Œ€ํ•ด ์ˆ˜ํ–‰ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ์ด API์— ์ง์ ‘ ์•ก์„ธ์Šคํ•˜๋Š” ๋Œ€์‹  ๋‹ค๋ฅธ ์‚ฌ๋žŒ์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” API๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ํ”„๋กœ์ ํŠธ๊ฐ€ ํ•˜๋‚˜ ๋˜๋Š” ๋งค์šฐ ์ œํ•œ์ ์ž…๋‹ˆ๋‹ค.

    • ๊ทธ๋Ÿฐ ๋‹ค์Œ ์ด๋Ÿฌํ•œ ๋ž˜ํผ ํŒ€๊ณผ ํ˜‘๋ ฅํ•˜์—ฌ ์ดˆ๊ธฐ์— ์˜ˆ์ •๋œ ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์— ๋Œ€ํ•ด ์•Œ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(๋ฐ˜์‘ ํ™•์žฅ์— ๋Œ€ํ•œ ์ œ์•ˆ๊ณผ ๋งค์šฐ ์œ ์‚ฌํ•จ).

Vue 3.0์˜ ๋ฆฌ์•กํ‹ฐ๋ธŒ ๋ชจ๋“ˆ(ref ๋˜๋Š” react)์„ ์ง์ ‘ ์ ์šฉํ•ด ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

@AnonymousArthur @vue/reactivity ํŒจํ‚ค์ง€์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•˜๋Š” ๊ฒฝ์šฐ ์†์„ฑ์— ๋ฐ˜์‘์„ฑ์„ ์ œ๊ณตํ•˜๊ณ  ์ƒ๋Œ€ ์ŠคํŠธ๋ฆผ(RxJ๊ฐ€ ๋ฌด์—‡์ธ์ง€)๊ณผ ์•„๋ฌด ๊ด€๋ จ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ์—ฌ๊ธฐ์—์„œ ๋…ผ์˜ํ•˜๋Š” ๊ฒƒ๊ณผ ์™„์ „ํžˆ ๊ด€๋ จ์ด ์—†์Šต๋‹ˆ๋‹ค.

@gund ์˜ˆ, ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด ๋Œ€ํ™”๋Š” ๊ฝค ์˜ค๋žœ ์‹œ๊ฐ„(4.5๋…„)์ด ๊ฑธ๋ฆฌ๊ณ  ์•„์ง ๋๋‚˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— subscribe/unsubscribe ๋˜๋Š” ngOnChange Handler๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ์‹ถ์ง€ ์•Š์€ ์‚ฌ๋žŒ๋“ค์„ ์œ„ํ•ด ๋งค์šฐ ๋น ๋ฅด๊ฒŒ ์•„์ด๋””์–ด๋ฅผ ํŒ๋‹ˆ๋‹ค(๊ทธ๋ ‡์ง€ ์•Š์„ ์ˆ˜๋„ ์žˆ์Œ). RxJS๋Š” ๋ฐ˜์‘์„ฑ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋ฉฐ ์ด ๋Œ€ํ™”(๋ชจ๋‘ ์ฝ์ง€๋Š” ์•Š์Œ)๋Š” ์ž…๋ ฅ ๊ฐ’์„ Observable๋กœ ๋ž˜ํ•‘ํ•˜์—ฌ ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๊ตฌ๋ฌธ ์„คํƒ•์œผ๋กœ ๋งํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ์ด๊ฒƒ์ด ๋ฉ‹์ง„ ์•„์ด๋””์–ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ด ์•„์ด๋””์–ด๊ฐ€ ์ •๋ง ์œ ์šฉํ•˜๊ณ  ์ฒ˜์Œ์— @robwormald ์˜ ํ”„๋กœํ† ํƒ€์ž…์ด ๋ฉ‹์ง€๊ฒŒ ๋ณด์ด์ง€๋งŒ ์ž ์žฌ์ ์ธ ์ด์ ๊ณผ ์˜ํ–ฅ์ด ์–ผ๋งˆ๋‚˜ ์ž‘์•„์•ผ ํ•˜๋Š”์ง€๋ฅผ ๊ณผ์†Œํ‰๊ฐ€ํ–ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋ช‡ ๊ฐ€์ง€ ๋‹จ์ ์„ ์ˆ˜์ •ํ•˜๊ธฐ ์œ„ํ•ด ํ•ด๋‹น ์†”๋ฃจ์…˜์— ์•ฝ๊ฐ„์˜ ์กฐ์ •์„ ์ œ์•ˆํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ธฐ๋ณธ์ ์œผ๋กœ๋Š” ๋™์ผํ•œ ์ ‘๊ทผ ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.

์ •์˜ ํ•  ๊ฐ๋„ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ @OInput() ๋ฐ ์œ ํ˜• EventReceiver<T> ์—ฐ์žฅ Observable<T> ๋˜ํ•œ ์ถ”๊ฐ€ํ•˜๋Š” .value ๊ฒŒํ„ฐ (๊ฐ™์€ BehaviorSubject<T> ).

@robwormald ์˜ ์˜ˆ์—์„œ์™€ ๊ฐ™์ด ์ƒ์œ„ ๊ตฌ์„ฑ ์š”์†Œ ์ธก์—์„œ๋Š” ์•„๋ฌด ๊ฒƒ๋„ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ฑฐ๊ธฐ์— Observable ๊ฐ’์„ ์ „๋‹ฌํ•˜๋ ค๋ฉด ์—ฌ์ „ํžˆ | async ํ•ฉ๋‹ˆ๋‹ค. ๋˜๋Š” ๊ด€์ฐฐํ•  ์ˆ˜ ์—†๋Š” ์œ ํ˜•์œผ๋กœ ์ „๋‹ฌํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. (ํ•ญ์ƒ ๊ทธ๋ ‡๋“ฏ์ด) ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค.

ํ•˜์œ„ ๊ตฌ์„ฑ ์š”์†Œ ์ธก ์—์„œ ์ œ์•ˆํ•œ ๋‚ด์šฉ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค(ํ•ด๋‹น ์ œ์•ˆ์—์„œ ์•ฝ๊ฐ„ ๋ฒ—์–ด๋‚จ).

@Component({ selector: "child" })
class Child {
  // Notice, this parallels the patterns of `@Output()`.
  @OInput() foo = new EventReceiver<MyType>();

  constructor() {
    // The reactive way to listen to input changes in the class.
    this.foo.subscribe((v) => {
      console.log('foo changed', v);
    });
    // Or you can bind to `foo | async` in the template.
  }

  // But this would also support less reactive patterns in parallel,
  // both for ease of migration and for cases where developers don't
  // want to migrate fully. 
  ngOnChanges(changes: SimpleChanges) {
    if (changes['foo']) {
      console.log('foo changed', changes['foo'].currentValue); // Unchanged
      console.log('foo changed', this.foo.value);  // Previously this would have been just `this.foo`
    }
  }
}

์ด์ œ ์ด ์ ‘๊ทผ ๋ฐฉ์‹์˜ ์ด์ ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ์ด๋Š” ์›ํ•˜๋Š” ๊ฒฝ์šฐ ์ƒ์œ„ ๋ฐ ํ•˜์œ„ ๊ตฌ์„ฑ์š”์†Œ ๋ชจ๋‘์—์„œ ํšจ๊ณผ์ ์œผ๋กœ ์™„์ „ํžˆ ๋ฐ˜์‘ํ•˜๋Š” ์„ค๊ณ„๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.
  • ์ƒ์œ„ ๊ตฌ์„ฑ ์š”์†Œ์—์„œ Angular์˜ ๊ธฐ์กด ์ž…๋ ฅ ๋””์ž์ธ ํŒจํ„ด์„ ์œ ์ง€ํ•˜๋ฏ€๋กœ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ๊ฐ•์ œ๋กœ ์ ์šฉ๋˜๊ฑฐ๋‚˜ ์ฃผ๋ณ€์—์„œ ๋””์ž์ธํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.
  • ๋ถ€๋ชจ์™€ ์ž์‹ ์ปจํ…์ŠคํŠธ๋Š” ์™„์ „ํžˆ ๋…๋ฆฝ์ ์ด๋ฉฐ ๋ถ€๋ชจ๋Š” ์ž์‹์ด Input ๋˜๋Š” OInput ์‚ฌ์šฉํ•˜๋Š”์ง€ ์•Œ ํ•„์š”๊ฐ€ ์—†์œผ๋ฏ€๋กœ ์ด ๋ณ€๊ฒฝ์œผ๋กœ ์ธํ•œ ๊ต์ฐจ ๊ตฌ์„ฑ ์š”์†Œ ๋ฒ„๊ทธ์˜ ์œ„ํ—˜์ด ์ œ๊ฑฐ๋ฉ๋‹ˆ๋‹ค.
  • Angular๋Š” ์ด์ „๊ณผ ๊ฐ™์ด ๊ธฐ์กด ์ˆ˜๋ช… ์ฃผ๊ธฐ ์ด๋ฒคํŠธ์— ๋ชจ๋‘ ์—ฐ๊ฒฐ๋œ ์ƒํƒœ๋กœ ์œ ์ง€ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์›ํ•˜๋Š” ๊ฒฝ์šฐ ๋‹จ์ผ ํ•˜์œ„ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋ถ€๋ถ„์ ์œผ๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•˜๋Š” ๊ฒƒ์ด ์ƒ๋Œ€์ ์œผ๋กœ ์‰ฝ์Šต๋‹ˆ๋‹ค.
  • Angular๋Š” ์ด ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ชจ๋“  EventReceiver ๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ takeUntil(ngOnDestroyEvent) ํ†ตํ•ด ํŒŒ์ดํ”„๋ฅผ ํฌํ•จํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ํŒŒ๊ดด๋  ๋•Œ ๊ตฌ๋… ์ทจ์†Œ๋ฅผ ๊ธฐ์–ตํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ด€์ฐฐ ๊ฐ€๋Šฅ ํ•ญ๋ชฉ์ด ์ž๋™์œผ๋กœ ์™„๋ฃŒ๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. . (์˜ˆ, ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ๊ฐ์†Œ!)
  • ์ด ํ•˜์œ„ ๊ตฌ์„ฑ ์š”์†Œ์—์„œ ์ด๊ฒƒ์€ ์˜ค๋Š˜๋‚ ์˜ @Output() ํŒจํ„ด๊ณผ ๋งค์šฐ ์œ ์‚ฌํ•˜๊ฒŒ ๋ณด์ด๊ณ  ๊ธฐ๋Šฅํ•˜๋ฏ€๋กœ ๋ฉ‹์ง„ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ์™€ ์ด๋“ค์„ ๋ฉ‹์ง€๊ฒŒ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ์ž ์žฌ์  ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

    • ์ฐธ๊ณ  ์‚ฌํ•ญ: ํ›„์† ์กฐ์น˜๋กœ ReplaySubject<T>(1) ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์–‘๋ฐฉํ–ฅ ๋ฐ”์ธ๋”ฉ์— ๋Œ€ํ•œ ๋™์ž‘์„ ๋ณด๋‹ค ์›ํ™œํ•˜๊ณ  ์ผ๊ด€๋˜๊ฒŒ ์—ฐ๊ฒฐํ•˜๋Š” @InputOutput() ๋ฅผ ์ œ์•ˆํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ทธ๊ฒƒ์€ ๋‚˜๋ฆ„์˜ ๋„์ „๊ณผ ๋…ผ๊ฑฐ๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์—ฌ๊ธฐ์—์„œ ์ œ์•ˆ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค .

  • ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์ƒˆ๋กœ์šด ์œ ํ˜•์˜ ์ƒ์šฉ๊ตฌ๋Š” ์—†์œผ๋ฉฐ @Output() ๋งŒํผ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค.
  • Angular๋Š” Observable ๊ฐ€ ๋ถ€๋ชจ์— ์˜ํ•ด ์ž…๋ ฅ๋˜๋Š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์— ๋Œ€ํ•ด ๋งค๋„๋Ÿฝ๊ฒŒ switch() ์ด๋ฏ€๋กœ ๋™์ผํ•œ Observable ์ธ์Šคํ„ด์Šค๋ฅผ ๊ณ ์ˆ˜ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ์•ฝํ•œ ๋ฐ˜์‘ ํŒจํ„ด์€ ํŠน๋ณ„ํ•œ ๊ฒฝ์šฐ๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค( switch() ed) ํ•˜์œ„ ๊ตฌ์„ฑ ์š”์†Œ.

๋‚ด๊ฐ€ ์„ ํƒํ•œ OInput ์ด๋ฆ„์— ๋Œ€ํ•œ ์ฐธ๊ณ  ์‚ฌํ•ญ: ๋ถ„๋ช…ํžˆ ๋…ผ์Ÿ์˜ ์—ฌ์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ "Observable Input"์˜ ์•ฝ์ž์ด๊ณ  ์ด๊ฒƒ์ด ๋ฏธ๋Ÿฌ๋ง๋˜๋Š” "Output"์ฒ˜๋Ÿผ ๋ณด์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ฐœ์ธ์ ์œผ๋กœ ๊ทธ ์ด๋ฆ„์„ ์ข‹์•„ํ•ฉ๋‹ˆ๋‹ค.

์นœ์• ํ•˜๋Š” Angular ํŒ€. 2020๋…„์—๋Š” ๋ฌด์—‡์ด๋“  ๊ธฐ๋Œ€ํ•ด์ฃผ์„ธ์š” :-)

๋˜ํ•œ @jcomputer ์†”๋ฃจ์…˜์€ ๋‚ด๊ฐ€ ์›ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์ด๋ฆ„์˜ ์—ด๋ ฌํ•œ ํŒฌ์€ ์•„๋‹ˆ์ง€๋งŒ @ViewChild ๊ฐ€ { read } ๊ฐ–๋Š” ๊ฒƒ๊ณผ ์œ ์‚ฌํ•œ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ:

@Input({ observable: true }) 
@Input({ asObservable: true }) 
@Input({ asSubject: true })

2020๋…„์— ๊ธฐ๋Œ€ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด ๋„ˆ๋ฌด ๋งŽ์Šต๋‹ˆ๋‹ค. :D ๋ฌผ๋ก  ์ด(๋ฐ ์œ„์— ๋‚˜์—ด๋œ ๋‹ค๋ฅธ ๋ฌธ์ œ)๊ฐ€ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์ด ์•„๋‹Œ ๋ฒ„๊ทธ๋กœ ๊ฐ„์ฃผ๋˜์ง€ ์•Š๋Š” ํ•œ. :)

https://twitter.com/ThomasBurleson/status/1283902827467886592
image

@fxck ์—ฌ๊ธฐ์—์„œ ์ธ๊ธฐ๊ฐ€ ์—†๋Š” ์˜๊ฒฌ์ด ์žˆ์„ ์ˆ˜ ์žˆ์ง€๋งŒ ์†”์งํžˆ ๋งํ•ด์„œ 2020๋…„์ด Angular ํŒ€์ด ์–‘์‹, ๋ผ์šฐํ„ฐ ๋“ฑ์— ๋Œ€ํ•œ ๋งŽ์€ ๋ฒ„๊ทธ๋ฅผ ์ˆ˜์ •ํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ๋‹ค๋ฉด ์ €๋Š” 0 ๊ธฐ๋Šฅ ์— ์ „ํ˜€ ํ™”๋ฅผ ๋‚ด์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค: ์–ด๊นจ๋ฅผ ์œผ์“ฑ:.

image

์ฆ‰, ์ตœ๊ทผ ์‚ฌ๊ฑด๊ณผ ๊ด€๋ จ๋œ ๋ฌธ์ œ์ผ ์ˆ˜ ์žˆ์œผ๋ฉฐ ํ˜„์žฌ Angular ํŒ€์—์„œ ๋ณต์žกํ•œ ์ผ์ด ์ง„ํ–‰๋˜๊ณ  ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๋“ค์ด ์ง€๊ธˆ๊นŒ์ง€ Angular๋ฅผ ์ ๊ทน์ ์œผ๋กœ ๊ตฌ์ถ•ํ•ด ์˜จ ์œ„๋Œ€ํ•œ ์‚ฌ๋žŒ๋“ค์ธ heart: ๋ฅผ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค

์ฃผ์ œ๋„˜์–ด์„œ ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ๋‚ ์•„ ๊ฐ€๋‹ค

@maxime1992 ๋‚˜๋„ ๊ดœ์ฐฎ์„๊ฑฐ์•ผ.

์—ฌ๊ธฐ์— ์ธ๊ธฐ๊ฐ€ ์—†๋Š” ์˜๊ฒฌ์ด ์žˆ์„ ์ˆ˜ ์žˆ์ง€๋งŒ ์†”์งํžˆ ๋งํ•ด์„œ 2020๋…„์ด Angular ํŒ€์ด ์–‘์‹, ๋ผ์šฐํ„ฐ ๋“ฑ์— ๋Œ€ํ•œ ๋งŽ์€ ๋ฒ„๊ทธ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ๋‹ค๋ฉด ๋‚˜๋Š” ๊ธฐ๋Šฅ ์ด

ํ•˜์ง€๋งŒ ๋‚˜๋ฅผ ๋ถˆ์•ˆํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ์€ ์šฐ๋ฆฌ ์—†์ด๋„ ์šฐ๋ฆฌ์—๊ฒŒ ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š” Angular ํŒ€ ๋‚ด๋ถ€์— ์žฅ๊ธฐ์ ์œผ๋กœ ๊ฑด๊ฐ•์— ํ•ด๋กœ์šด HR ํ”„๋กœ์„ธ์Šค๊ฐ€ ์žˆ๋‹ค๋Š” ์‚ฌ์‹ค์ž…๋‹ˆ๋‹ค. ํŠนํžˆ ์ด ์ง€์—ญ์— ๋Œ€ํ•œ ๋Œ€๊ทœ๋ชจ ํˆฌ์ž์˜ ๊ด€์ ์—์„œ.

๋‚ด POV์—์„œ ๊ทธ๋“ค์€ ์ฃผ๋กœ BOT๋ฅผ ํ†ตํ•ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜์—ฌ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์‘๋‹ต ์—†์ด ๋– ๋‚˜๊ณ  ๋ด‡์— ์˜ํ•ด ๋‹ซํž™๋‹ˆ๋‹ค.,.. :-/

@montella1507 ์•„๋‹ˆ์˜ค, ์ด๊ฒƒ์€ ์‚ฌ์‹ค์ด ์•„๋‹™๋‹ˆ๋‹ค. ๋ด‡์€ ์ด๋ฏธ ๋‹ซํžŒ ๋ฌธ์ œ๋งŒ ์ž ๊ธ‰๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  Angular ํŒ€์›๋“ค์ด ์ƒˆ๋กœ์šด ์ด์Šˆ๊ฐ€ ๋‚˜์™”์„ ๋•Œ ์„ค๋ช…ํ•˜๊ณ  ์žฌํ˜„ํ•ด์•ผ ํ•  ์‚ฌํ•ญ์„ ์„ค๋ช…ํ•˜๋ ค๊ณ  ํ•  ๋•Œ ๋งŽ์€ ๊ฒฝ์šฐ์— ๋งŽ์€ ๋…ธ๋ ฅ์„ ๊ธฐ์šธ์ด๋Š” ๊ฒƒ์€ ์ด๋ฏธ ์‚ฌ์‹ค์ž…๋‹ˆ๋‹ค. ์‹œ๊ฐ„์ด ๋งŽ์ด ๊ฑธ๋ฆฌ๋Š” ๊ณผ์ •์ด๋ฉฐ ๋งŽ์€ ์ธ๋‚ด๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

Angular ํŒ€์„ ๋น„๋‚œํ•˜๊ณ  ๊ธฐ๋Šฅ๊ณผ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๋นจ๋ฆฌ ์–ป์ง€ ๋ชปํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ๋ถˆํ‰ํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์„ ์œ„ํ•ด:
๋‚˜๋Š” ๋‹น์‹ ์˜ ๊ณ ํ†ต์„ ์ดํ•ดํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋˜ํ•œ Angular์—์„œ ์ด ๊ธฐ๋Šฅ์„ ๋ณด๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๊ฐœ์ธ์ ์œผ๋กœ ์ข‹์•„ํ•˜์ง€ ์•Š๋Š” ๋งŽ์€ ๊ฒƒ๋“ค์„ ๋ณ€๊ฒฝํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ Angular๋Š” ๋ฐ˜์ง์ด๋Š” ์ƒˆ ์žฅ๋‚œ๊ฐ์ด ๋ชจ๋‘ ์žˆ๊ณ  ๋ฆด๋ฆฌ์Šค๋งˆ๋‹ค ์ˆ˜๋งŽ์€ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ์•„๋‹ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ทธ๊ฑด ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค. ๋ณด๋‹ค ์—”ํ„ฐํ”„๋ผ์ด์ฆˆ๊ธ‰์„ ๋ชฉํ‘œ๋กœ ํ•˜๊ณ  ์•ˆ์ •์„ฑ๊ณผ ์‹ ๋ขฐ์„ฑ์„ ์ œ๊ณตํ•˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  Angular๋Š” ์ ์–ด๋„ ๋‚ด ๊ฒฝํ—˜์— ๋น„์ถ”์–ด ๋ณผ ๋•Œ ์ž˜ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

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

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

@manfreed ์‚ฌ๋žŒ๋“ค์€ ๋ฐ˜์ง์ด๋Š” ์ƒˆ ์žฅ๋‚œ๊ฐ์„ ์š”๊ตฌํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ํ”„๋ ˆ์ž„์›Œํฌ ๋””์ž์ธ์˜ ๊ฐ„๊ณผ์— ๋Œ€ํ•œ ์ˆ˜์ •์„ ์š”๊ตฌํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ ์šฐ๋ฆฌ๋Š” ํ•ต์‹ฌ ๊ธฐ๋Šฅ์„ ์œ„ํ•ด ๋•Œ๋•Œ๋กœ Observable์„ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๊ณ  ๋•Œ๋กœ๋Š” Observable์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ๊ฒƒ์„ ์‹ซ์–ดํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์€ ์ขŒ์ ˆํ•ฉ๋‹ˆ๋‹ค. ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ๊ฒƒ์„ ์ข‹์•„ํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์€ ์ขŒ์ ˆํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์šฐ๋ฆฌ ์ค‘ ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด ์šฐ๋ฆฌ๊ฐ€ ํฌ๊ธฐํ•˜๊ณ  ๋‹ค๋ฅธ ํ”„๋ ˆ์ž„์›Œํฌ๋กœ ๋„˜์–ด๊ฐ„ ์ƒํ™ฉ์— ๋„ˆ๋ฌด ์‹ค๋งํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ์•ฝ๊ฐ„์˜ ๋ฐฉํ–ฅ์„ฑ์ธ Angular๋ฅผ ๊ณ„์† ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์—ˆ๊ณ  ์ •๋ง ํ›Œ๋ฅญํ•œ ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ๋  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ž˜๋ชป๋œ ๊ด€๋ฆฌ, ์‹ค์šฉ์ฃผ์˜์˜ ๋ถ€์กฑ, ์‹ค์ˆ˜์— ๋Œ€ํ•œ ๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๋ฌผ์€ ๋ชจ๋‘ ๊ฐ๊ด€์ ์œผ๋กœ ์‹ค๋ง์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค.

@insidewhy ์ธ๋‚ด์‹ฌ์„

๋กœ๋“œ๋งต์—์„œ ์•ž์„œ ์–ธ๊ธ‰ํ•œ ํŠน์ • ๋ฌธ์ œ์— ๋Œ€ํ•œ ์–ธ๊ธ‰์€ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ์ €๋Š” ์Šฌํ”„๊ฒŒ๋„, ์–ธ๊ธ‰, ์ธ์ •, ...์ด ๋…ผ์˜๊ฐ€ Angular discord์— ์ด์–ด์ง€๊ธฐ๋ฅผ ์ •๋ง๋กœ ๋ฐ”๋ž์Šต๋‹ˆ๋‹ค.

image

๋‚˜๋Š” ๊ทธ๋“ค์—๊ฒŒ ์˜์‹ฌ์˜ ์—ฌ์ง€๋ฅผ ์ฃผ์—ˆ๊ณ  ๊ทธ ์ค‘๊ฐ„ ๋กœ๋“œ๋งต ๊ธฐ์‚ฌ ์˜ ๋…ผํ‰์—์„œ ๋ฌผ์—ˆ์Šต๋‹ˆ๋‹ค. Minko์˜ ์‘๋‹ต:

image

๊ทธ๋Š” ๋ช‡ ๋‹ฌ ์ „์— ์—ฌ๊ธฐ์—์„œ ๋งํ•œ ๊ฒƒ์„ ๊ฑฐ์˜ ๋ฐ˜๋ณตํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ rxjs ๊ด€๋ จ ๋ฌธ์ œ ์ค‘ ์–ด๋Š ๊ฒƒ๋„ ๊ณง ์ˆ˜์ •๋˜์ง€ ์•Š์„ ๊ฒƒ์ด๋ฏ€๋กœ ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค.

๋‚ด ์š”์ ์„ ์ดํ•ดํ•˜๋Š” ๊ฒƒ์€ ๋๋‚ฌ์ง€๋งŒ ๋งˆ์ง€๋ง‰์œผ๋กœ ํ•œ ๋ฒˆ๋งŒ ๋” ์‹œ๋„ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. Angular๊ฐ€

  • ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ์ˆ˜๋ช… ์ฃผ๊ธฐ
  • ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ์ž…๋ ฅ
  • ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ํ…œํ”Œ๋ฆฟ ์ด๋ฒคํŠธ

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

@fxck :+1: ํ™•์‹คํžˆ.

  • ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ์ˆ˜๋ช… ์ฃผ๊ธฐ
  • ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ์ž…๋ ฅ
  • ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ํ…œํ”Œ๋ฆฟ ์ด๋ฒคํŠธ

@insidewy ์ธ๋‚ด์‹ฌ์„ ๊ฐ€์ง€๊ณ 

์‚ฌ๋žŒ๋“ค์—๊ฒŒ 5๋…„ ์ด์ƒ์˜ ์ธ๋‚ด๋ฅผ ์š”๊ตฌํ•˜๋Š” ๊ฒƒ์€ ๋งŽ์€ ๊ฒฝ์Ÿ์ž๋“ค์ด ๊ด€์‹ฌ์„ ๋ฐ›๊ธฐ ์œ„ํ•ด ๊ฒฝ์Ÿํ•˜๋Š” ๊ฒฝ์ฃผ์—์„œ ๊ณผ๊ฑฐ๋ฅผ ๋‹ฌ๋ฆฌ๊ณ  ์žˆ์„ ๋•Œ ๊ทธ๋‹ค์ง€ ์‹ค์šฉ์ ์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

@ insidewhy ๋” ์ผ๋ฐ˜์ ์œผ๋กœ ์˜๋ฏธํ–ˆ์Šต๋‹ˆ๋‹ค.

@fxck Google์€ 4000๊ฐœ์˜ ์•ฑ์ด (๋‚ด ๋งˆ์ง€๋ง‰ ๊ณ„์‚ฐ์— ์˜ํ•ด) ๊ฐ์ง€๊ณ  ๋ณธ์งˆ์ ์œผ๋กœ ๋งค์šฐ ์œ ์‚ฌํ•˜๋ฉฐ ์ด๋Ÿฌํ•œ ํ”„๋กœ์ ํŠธ์™€ ๋™๋ฃŒ ๊ฒ€ํ†  ์‚ฌ์ด๋ฅผ ์ „ํ™˜ํ•˜๋Š” ๊ฒƒ์ด (๋‚ด ์ƒ๊ฐ์—) ๋งค์šฐ ๋งค๋„๋Ÿฝ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ ํšŒ์‚ฌ์—์„œ๋„ Angular์˜ ํฐ ์ด์  ์ค‘ ํ•˜๋‚˜๋Š” ๋‚ด๊ฐ€ ๋‹ค๋ฅธ ํŒ€์˜ ์ฝ”๋“œ๋ฅผ ๊ฒ€ํ† ํ•˜์ง€ ์•Š๊ณ ๋„ ๋™๋ฃŒ ๊ฒ€ํ† ๊ฐ€ ์ „์ฒด ์กฐ์‚ฌ๋ฅผ ์‹œ์ž‘ํ•˜์ง€ ์•Š๋Š” ์ƒํƒœ์— ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ด์ œ ์ด๋Ÿฌํ•œ ์œ ์šฉํ•œ RxJS ๋ฐ”๋กœ ๊ฐ€๊ธฐ๋ฅผ ์ฝ”์–ด์— ๊ตฌํ˜„ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ์š”? ํŠน์ • ๊ฒฝ์šฐ์— ์–ด๋–ค ํŽธํ–ฅ์ด ์˜ฌ๋ฐ”๋ฅธ์ง€์— ๋Œ€ํ•œ ๋ช…ํ™•ํ•œ ์ง€์นจ ์—†์ด ์ ˆ์ฐจ์  ํŽธํ–ฅ ๋Œ€ ๋ฐ˜์‘์  ํŽธํ–ฅ์œผ๋กœ ๋๋‚  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ๊นŒ์ง€์˜ ํ† ๋ก ์„ ์ฝ์€ ํ›„ Angular ํŒ€์˜ ๋Œ€๋‹ต์€ "์ด๊ฒƒ์€ ๋‚ฎ์€ ์šฐ์„  ์ˆœ์œ„์ž…๋‹ˆ๋‹ค"(๊ท€ํ•˜์˜ ํ๋ฆ„์—์„œ ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด)๊ฐ€ ์•„๋‹ˆ๋ผ ์‹ค์ œ๋กœ "์šฐ๋ฆฌ๋Š” ํŽธ์„ ๋“ค๊ณ  ์‹ถ์ง€ ์•Š์Šต๋‹ˆ๋‹ค"์— ๋” ๊ฐ€๊นŒ์šด ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

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

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

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

Angular ํŒ€ ๊ตฌ์„ฑ์› ์ค‘ ํ•œ ๋ช…์„ ์ธ์šฉํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

image

๊ทธ๊ฑด ๊ทธ๋ ‡๊ณ , ์ด๊ฒƒ๋“ค(๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ์ˆ˜๋ช… ์ฃผ๊ธฐ, ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ์ž…๋ ฅ, ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ํ…œํ”Œ๋ฆฟ ์ด๋ฒคํŠธ)์— ๋Œ€ํ•ด ์ „ํ˜€ ๋ฐœ์ „๋œ ๊ฒƒ์ด ์—†์Šต๋‹ˆ๋‹ค.

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

์ƒํƒœ ๊ด€๋ฆฌ์™€ ์ด๊ฒƒ์˜ ์ฐจ์ด์ ์€ ์ƒํƒœ ๊ด€๋ฆฌ๋Š” ์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ด๋ฅผ ๋ฐฉ์ง€ํ•˜๋Š” ์•ต๊ทค๋Ÿฌ ์ฝ”์–ด ๋‚ด๋ถ€์—๋Š” ์•„๋ฌด๊ฒƒ๋„ ์—†๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ถˆํ–‰ํžˆ๋„ Angular๋Š” ๋‚ด๊ฐ€ ์–ธ๊ธ‰ํ•œ ์„ธ ๊ฐ€์ง€ ๋ชจ๋‘๋ฅผ ์ ์ ˆํ•˜๊ฒŒ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. (์ˆ˜์ •: ๋Œ“๊ธ€ ๋งํฌ ์ˆ˜์ •)

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

์ง€๊ธˆ๊นŒ์ง€์˜ ํ† ๋ก ์„ ์ฝ์€ ํ›„ Angular ํŒ€์˜ ๋Œ€๋‹ต์€ "์ด๊ฒƒ์€ ๋‚ฎ์€ ์šฐ์„  ์ˆœ์œ„์ž…๋‹ˆ๋‹ค"(๊ท€ํ•˜์˜ ํ๋ฆ„์—์„œ ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด)๊ฐ€ ์•„๋‹ˆ๋ผ ์‹ค์ œ๋กœ "์šฐ๋ฆฌ๋Š” ํŽธ์„ ๋“ค๊ณ  ์‹ถ์ง€ ์•Š์Šต๋‹ˆ๋‹ค"์— ๋” ๊ฐ€๊นŒ์šด ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๋„ค, ๊ทธ๋ฆฌ๊ณ  ๋ฌด์„ญ์Šต๋‹ˆ๋‹ค.

@fxck ๋‚˜๋Š” ์šฐ๋ฆฌ๊ฐ€ ์ด๊ฒƒ์— ๋Œ€ํ•ด ๊ฐ™์€ ํŽ˜์ด์ง€์— ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ํฌ๋Ÿผ์ด๋‚˜ ๋™๋ฃŒ ์—”์ง€๋‹ˆ์–ด๋“ค๊ณผ ํ•จ๊ป˜ RxJS๋ฅผ ์–ธ๊ธ‰ํ•  ๋•Œ๋งˆ๋‹ค ์ธ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋Œ€๋ถ€๋ถ„์˜ ์ธ์šฉ๋ฌธ์€ "์•„์ง๋„ ์ด๊ฒƒ์„ ์ดํ•ดํ•˜์ง€ ๋ชปํ•˜๋Š”๋ฐ ์–ด๋–ป๊ฒŒ ๋” ๋ฐฐ์šฐ๋‚˜์š”?"๋ผ๊ณ  ๋งํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๋˜๋Š” "์šด์˜์ž๊ฐ€ ์–ผ๋งˆ๋‚˜ ๋งŽ์€์ง€ ์••๋„๋ฉ๋‹ˆ๋‹ค." ๋˜๋Š” "์ด PR์—์„œ ์ด ํŒŒ์ดํ”„๋ผ์ธ์„ ์ฝ๋Š” ๋ฐ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค." ์ˆ™๋ จ๋œ RxJS ์—”์ง€๋‹ˆ์–ด 1๋ช…๋‹น 15๋ช…์˜ ์ˆ™๋ จ๋œ Angular ์—”์ง€๋‹ˆ์–ด๊ฐ€ ๋ˆˆ์น์„ ์ฐŒํ‘ธ๋ฆฌ๊ณ  ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๋„ค, ๊ทธ๋ฆฌ๊ณ  ๋ฌด์„ญ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ์šฐ๋ฆฌ๊ฐ€, ์กฐ๊ธˆ ๊ณผ์žฅํ•˜์ง€ "ํ•„์š”" @angular/core ์ด๋Ÿฌํ•œ ํŒจํ„ด์„ ๊ฐ€์ง€๊ณ , ์‚ฌ์‹ค ์–ด๋–ค ํ”„๋กœ์ ํŠธ์— ์˜ค๋Š˜ ์‚ฌ์šฉํ•  ์ˆ˜์žˆ๋Š”์ด ๋ฌธ์ œ์—์„œ ๋งŽ์€ ๋งŽ์€ ๋ณ€์ข…๊ณผ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์•ž์„œ ์–ธ๊ธ‰ํ•œ ์˜ต์…˜์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ ์žˆ์–ด ์œ ์ผํ•œ ์ฃผ์ €๋Š” ๋ฏธ๋ž˜์— Angular๊ฐ€ ํ‘œ์ค€ @angular/core ๋Œ€์ฒดํ’ˆ์œผ๋กœ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•ด์•ผ ํ•  ์ˆ˜๋„ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ npm uninstall ํ•˜๊ณ  ๋ชจ๋“  typescript ์˜ค๋ฅ˜๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ๊ฒƒ์ด ์ •๋ง๋กœ ๊ทธ๋ ‡๊ฒŒ ์–ด๋ ค์šด๊ฐ€์š”?

๋ชจ๋“  ๊ฐ๋„ ํ”„๋กœ์ ํŠธ์— ์˜ํ–ฅ์„ ๋ฏธ์น˜๊ณ  ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ๋ฌธ์„œํ™”ํ•˜๊ณ  ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•˜๋Š” ๋ฐ ์ˆ˜๋งŽ์€ ์‹œ๊ฐ„์ด ํ•„์š”ํ•œ ์ฃผ์š” ์•„ํ‚คํ…์ฒ˜ ๊ฒฐ์ •์€ ์ €์—๊ฒŒ ํ›จ์”ฌ ๋” ๋ฌด์„ญ๊ฒŒ ๋ณด์ž…๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ์•ฝ๊ฐ„์˜ ์Œ๊ณก์„ ์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ํŒจํ„ด์„ ๊ฐ–๊ธฐ ์œ„ํ•ด @angular/core๊ฐ€ "ํ•„์š”"ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์‚ฌ์‹ค ์ด ๋ฌธ์ œ์—๋Š” ์˜ค๋Š˜๋‚  ๋ชจ๋“  ํ”„๋กœ์ ํŠธ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋งŽ์€ ๋ณ€ํ˜•๊ณผ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

์•„๋‹ˆ์š”, ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ฐ ์†”๋ฃจ์…˜์—๋Š” ํ•ดํ‚น์ด ํ•„์š”ํ•˜๊ฑฐ๋‚˜ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ๋Š” ๋‚ด๋ถ€ API์— ์˜์กดํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์ด ์š”์ ์ž…๋‹ˆ๋‹ค. @insidewhy ๊ฐ€ https://github.com/angular/angular/issues/5689#issuecomment -630661006์ด๋ผ๊ณ  ๋งํ•œ ๊ฒƒ๊ณผ ํ…œํ”Œ๋ฆฟ ์ด๋ฒคํŠธ ์ŠคํŠธ๋ฆผ์— ๋Œ€ํ•ด ๊ทธ ์•„๋ž˜์—์„œ ๋งํ•œ ๊ฒƒ์„ ์ฝ์œผ์‹ญ์‹œ์˜ค.

// ๋Œ“๊ธ€ ์ˆ˜์ • ๋งํฌ ์ˆ˜์ •

์•„๋‹ˆ์š”, ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ฐ ์†”๋ฃจ์…˜์—๋Š” ํ•ดํ‚น์ด ํ•„์š”ํ•˜๊ฑฐ๋‚˜ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ๋Š” ๋‚ด๋ถ€ API์— ์˜์กดํ•ฉ๋‹ˆ๋‹ค.

์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ ์ด๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋ ค๋ฉด ์–ด๋–ค ๋‚ด๋ถ€ API ๋˜๋Š” ์œ ํ˜•์„ ๊ณต๊ฐœ/์ผ๋ฐ˜ํ™”ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์‹ญ๋‹ˆ๊นŒ? ๋งŒ์•ฝ ์ด ๋””์ž์ธ์ด ์•ž์œผ๋กœ ๋‚˜์•„๊ฐˆ ๋ฐฉํ–ฅ์ด ๋ช…ํ™•ํ•˜์ง€ ์•Š์•„์„œ ํ™€๋”ฉ ํŒจํ„ด์ด๋ผ๋ฉด, ๊ณ„์†ํ•ด์„œ ๊ฐ™์€ ๋“œ๋Ÿผ์„ ๋‘๋“œ๋ฆฌ๋Š” ๊ฒƒ๋ณด๋‹ค ์šฐ๋ฆฌ ์ž์‹ ์˜ ๋””์ž์ธ์„ ํ—ˆ์šฉํ•˜๋„๋ก ์š”์ฒญํ•˜๋Š” ๊ฒƒ์ด ์ ์ ˆํ•ด ๋ณด์ž…๋‹ˆ๋‹ค.

@insidewhy ๊ฐ€ ์ฝ”์–ด ๋‚ด๋ถ€์—์„œ ์ˆ˜ํ–‰ํ•˜๋ ค๊ณ  ์‹œ๋„ํ•œ ๋‹ค๋ฅธ ๋Œ“๊ธ€์„ ์ฝ์–ด

image

@fxck ์ €๋Š” ์ด๊ฒƒ์„ ํ•ต์‹ฌ์œผ๋กœ ๊ตฌํ˜„ํ•˜๋ ค๋Š” ์‹œ๋„์˜ ์—ญ์‚ฌ๋‚˜ ์ด ๋ฌธ์ œ๊ฐ€ 5๋…„ ๋™์•ˆ ์–ด๋–ป๊ฒŒ ๊ณต๊ฐœ๋˜์—ˆ๋Š”์ง€์— ๋Œ€ํ•ด ๋…ผ์˜ํ•˜์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ปค๋ฎค๋‹ˆํ‹ฐ๊ฐ€ ์Šค์Šค๋กœ ๋””์ž์ธ์„ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ๋„๋ก ๋‚ด๋ถ€๋ฅผ ๊ณต๊ฐœํ•˜์ง€ ๋ชปํ•˜๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

Yo @insidewhy , ์ด๊ฒƒ์ด ๋‹น์‹ ์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์˜์กดํ•˜๋Š” ์œ ํ˜• ๊ฒ€์‚ฌ ํ•ดํ‚น์ธ์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค. ๋ถ„๋ช…ํžˆ TS 4.0์„ ์‚ฌ์šฉํ•˜์—ฌ ๋” ์ด์ƒ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ดˆ๊ธฐํ™” ์ „์— 'serviceStackId$' ์†์„ฑ์ด ์‚ฌ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.ts(2729)

image

Yo @insidewhy , ์ด๊ฒƒ์ด ๋‹น์‹ ์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์˜์กดํ•˜๋Š” ์œ ํ˜• ๊ฒ€์‚ฌ ํ•ดํ‚น์ธ์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค. ๋ถ„๋ช…ํžˆ TS 4.0์„ ์‚ฌ์šฉํ•˜์—ฌ ๋” ์ด์ƒ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์•„๋‹ˆ์š”, ํ…œํ”Œ๋ฆฟ ์ปดํŒŒ์ผ๋Ÿฌ์— ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋‹ค๋ฅธ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ œ๊ธธ. ์•„ ๊ธ€์Ž„. ๋‹น์‹ ์ด ๊ทธ๊ฒƒ์„ ๊ณ ์น˜๊ณ  ์‹ถ๋‹ค๋ฉด ๋‚ด๊ฐ€ ๋‹น์‹ ์„ ๊ด€๋ฆฌ์ž ๋ชฉ๋ก์— ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@fxck ์‹ค์ œ๋กœ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ๊ธฐ๋ฐ˜ ์†์„ฑ์€ ์ƒ์„ฑ์ž๊ฐ€ ์‹คํ–‰๋  ๋•Œ๊นŒ์ง€ ์ฃผ์ž…๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ ngOnInit์—์„œ ํŒŒ์ดํ”„๋œ ์—ฐ์‚ฐ์ž๋ฅผ ํ• ๋‹นํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ด๊ฒƒ์€ ์‹ค์ œ๋กœ ์ฝ”๋“œ์— ํ•ฉ๋ฒ•์ ์ธ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.

@insidewhy ๋‚˜๋Š” ํ™•์‹คํžˆ TS4 ์ด์ „์— ์ผ์„ ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด๊ฒƒ์„ ํ™•์ธ

function ObservableInput() {
  return (target: any, propertyKey: any) => {
    Object.defineProperty(target, propertyKey, {
      set(value: any) {
        console.log(target, propertyKey, value);
      },
      get() {
        return 'ObservableInput modified value';
      },
    })
  }
}

class Foo {
    @ObservableInput()
    bar = 'original bar value';

    baz = this.bar;

    constructor() {
        console.log('loggging this.baz', this.baz);
    }
}

new Foo();

๊ทธ๊ฒƒ์€ ๊ธฐ๋ก

this.baz ObservableInput ์ˆ˜์ • ๊ฐ’ ๋กœ๊น…

๊ทธ๋ž˜์„œ ๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ์—ฌ์ „ํžˆ ์ž‘๋™ํ•ด์•ผํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. TS4์—์„œ๋งŒ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ํ•ด๋‹น ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ๋‚ด๋ถ€์— ๊ฐ’์„ ๊ฐ€์ง„ get ๊ฐ€ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ๊นจ๋‹ซ์ง€ ๋ชปํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ถˆํ‰ํ•ฉ๋‹ˆ๋‹ค.

์ €๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Input prop ๋ณ€๊ฒฝ์„ ๊ฐ์ง€ํ•˜๊ณ  Input prop์˜ ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ๋ฒ„์ „์„ ๋งŒ๋“ค๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์ฝ”๋“œ์ƒŒ๋“œ๋ฐ•์Šค ๋ฐ๋ชจ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

์ž‘๋™ ๋ฐฉ์‹์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

// subjectize.ts
export function Subjectize(keyToWatch: string): PropertyDecorator {
  return (proto: any, propKey: string) => {
    const internalKey = Symbol(keyToWatch);
    Object.defineProperties(proto, {
      [keyToWatch]: {
        get() {
          return this[internalKey];
        },
        set(value) {
          this[internalKey] = value;
          this[propKey].next(value);
        }
      }
    });
  };
}
// counter.component.ts
import { Component, Input } from "@angular/core";
import { ReplaySubject } from "rxjs";
import { Subjectize } from "./subjectize";

@Component({
  selector: "app-counter",
  templateUrl: "./counter.component.html",
  styleUrls: []
})
export class CounterComponent {
  @Input()
  count: number;

  @Subjectize("count")
  count$ = new ReplaySubject(1);
}

@wmaurer๊ฐ€ ์ง€์ ํ–ˆ๋“ฏ์ด @Subjectize ๋Š” ์ž‘์—…์„ ์™„๋ฃŒํ•˜๊ธฐ ์œ„ํ•ด "์„คํƒ•"์œผ๋กœ ์ทจ๊ธ‰๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

getter/setter ์‚ฌ์šฉํ•˜์—ฌ ์ž…๋ ฅ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๊ฐ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์„ค๋ช… ํ•˜๋Š” Angular์˜ ๊ณต์‹ ๊ฐ€์ด๋“œ

@hankchiutw ๊ทธ ์†”๋ฃจ์…˜์€ ๋‚ด @BindObservable ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์™€ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค. https://github.com/PSanetra/bind-observable#usage

@hankchiutw ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค

ReplaySubject๋ฅผ 1๋กœ ์ดˆ๊ธฐํ™”ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋Œ€์‹  BehaviorSubject๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ๋กœ ์„ ํƒํ–ˆ์Šต๋‹ˆ๋‹ค.
๋˜ํ•œ Subjectize์—์„œ ์ง์ ‘ ๊ฐ’์„ ์ดˆ๊ธฐํ™”ํ–ˆ์Šต๋‹ˆ๋‹ค.

export function Subjectize<T>(keyToWatch: string): PropertyDecorator {
  return (target: Object, propKey: string) => {
    const internalKey = Symbol(keyToWatch);
    Object.defineProperties(target, {
      [keyToWatch]: {
        get(): T {
          return this[internalKey];
        },
        set(value: T) {
          this[internalKey] = value;

          if (this[propKey]) {
            this[propKey].next(value);
          } else {
            this[propKey] = new BehaviorSubject(value);
          }
        }
      }
    });
  };
}

@Component({
    changeDetection: ChangeDetectionStrategy.OnPush,
    selector: 'rol-bla',
    templateUrl: 'bla.html',
    styleUrls: [ 'bla.scss' ]
})
export class BlaComponent implements OnInit {
    @Input() world: World;
    @Subjectize<World>('world') world$: BehaviorSubject<World>;

    // ...
}

๊ด€๋ จ ์†์„ฑ์—์„œ ์ถ”์ธกํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— "Subjectized" ์†์„ฑ์— ๋Œ€ํ•œ ์œ ํ˜• ์ž‘์„ฑ์„ ํ”ผํ•  ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

๊ฟˆ์€ ๊ทธ๋ ‡๊ฒŒ ํ•  ์ˆ˜ ์žˆ๊ณ  ๊ด€๋ จ Subject ์†Œํ’ˆ(๋‚ด ๊ฒฝ์šฐ์—๋Š” world$)์„ BehaviorSubject๋กœ ์ž๋™ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.๊ทธ๋ฆฌ๊ณ  ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ดˆ๊ธฐํ™”๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

export class BlaComponent implements OnInit {
    @Input() @Subjectize() world: World;

    // ...
}

@mparpaillon ์ œ์•ˆํ•œ ๋””์ž์ธ์€ https://github.com/PSanetra/bind-observable ์—์„œ ์ˆ˜ํ–‰๋˜๋Š” ๋ฐฉ์‹๊ณผ ๊ฑฐ์˜ ๊ฐ™์Šต๋‹ˆ๋‹ค.
์œ ์ผํ•œ ์ฐจ์ด์ ์€ @BindObservable() ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๊ฐ€ ํ›„๋“œ ์•„๋ž˜์—์„œ ReplaySubject๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ํ•ด๋‹น ์ฃผ์ œ์— ์ดˆ๊ธฐ ๊ฐ’์ด ํฌํ•จ๋˜๋„๋ก ํ•˜๋ ค๋ฉด ๋ฐ”์ธ๋”ฉ๋œ ์†์„ฑ๋„ ๋ช…์‹œ์ ์œผ๋กœ ์ดˆ๊ธฐํ™”ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(์†์„ฑ ์œ ํ˜•์ด ์ •์˜๋˜์ง€ ์•Š์€ ๊ฐ’์ด๋‚˜ null ๊ฐ’์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ •์˜๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ์—๋„).

์Šคํƒ๋ธ”๋ฆฌ์ธ  ์˜ˆ์‹œ

@Component({
  selector: 'app-my-component',
  templateUrl: './my-component.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class MyComponentComponent {
  @Input()
  @BindObservable()
  counter: number;
  counter$: ReplaySubject<number>;
}

@PSanetra ์—๊ฒŒ ๊ฐ์‚ฌํ•˜์ง€๋งŒ ๋‚ด ์†”๋ฃจ์…˜(์‹ค์ œ๋กœ๋Š” Hank ์†”๋ฃจ์…˜)์„ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค.

@mparpaillon ๋‚˜๋Š” ๋‹ค๋ฅธ ๋ฐ๋ชจ ์—์„œ ๋‹น์‹ ์˜ ๊ฟˆ(ํ•˜)์„ ์œ„ํ•ด ๋ญ”๊ฐ€๋ฅผ ์‹œ๋„ํ–ˆ์Šต๋‹ˆ๋‹ค.

์‚ฌ์šฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

export class CounterComponent {
  @Input()
  @Subjectize()
  count: number;

  @Input()
  @Subjectize("myCount$")
  anotherCount: number;
}

์—ฌ๊ธฐ์„œ ์ฃผ์ œ๊ฐ€ ์ง€์ •๋œ ์†Œํ’ˆ ์ด๋ฆ„์„ ์ง€์ •ํ•˜๋„๋ก ์„ ํƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ธฐ์ˆ ์ ์œผ๋กœ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ๊ฐœ๋ฐœ์ž์—๊ฒŒ๋Š” ๋ชจํ˜ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์ƒˆ ํด๋ž˜์Šค ๋ฉค๋ฒ„๊ฐ€ ๋‚ด๋ถ€์—์„œ ์ƒ์„ฑ๋˜๊ธฐ ๋•Œ๋ฌธ์—).

@hankchiutw ๊ฐ์‚ฌ

Capture dโ€™eฬcran 2020-11-12 aฬ€ 10 11 50

๋˜ํ•œ ๋ชจํ˜ธ์„ฑ์— ๋Œ€ํ•ด ์˜ณ์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค ... ๋‹ค์‹œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค

Typescript์—์„œ๋Š” count$ ๋˜๋Š” myCount$๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

ํด๋ž˜์Šค ๋ฉค๋ฒ„๋ฅผ "count" ๋ฐ "anotherCount"๋กœ ์„ ์–ธํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— "myCount$" ๋ฐ "count$"์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์•„๋ฌด๋ฐ๋„ ์„ ์–ธํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ๋‹จ์ˆœํžˆ ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์•Œ์•„์š”... ๊ทธ๊ฒŒ ์š”์ ์ž…๋‹ˆ๋‹ค. Decorator์—์„œ ์„ ์–ธํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ฐพ๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. @hankchiutw ๊ฐ€ ์†”๋ฃจ์…˜์„ ์ œ๊ณตํ–ˆ๋Š”๋ฐ ๊ทธ๋Œ€๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@mparpaillon ๋‚ด ์†”๋ฃจ์…˜์„ ์‚ดํŽด๋ณด์‹ญ์‹œ์˜ค: https://github.com/Futhark/ngx-observable-input

@Futhark ์˜ค ๋ฅ๋‹ค! ๊ณ ๋งˆ์›Œ

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰