Angular.js: 컨트둀러 후크 μˆœμ„œ($onInit 전에 $onChanges 호좜)

에 λ§Œλ“  2016λ…„ 12μ›” 16일  Β·  9μ½”λ©˜νŠΈ  Β·  좜처: angular/angular.js

κΈ°λŠ₯ 을 μš”μ²­ν•˜κ±°λ‚˜ 버그λ₯Ό 보고 ν•˜μ‹œκ² μŠ΅λ‹ˆκΉŒ?
μ›ν•œκ±΄μ§€ 버그인지 λͺ¨λ₯΄κ² μŒ

ν˜„μž¬ 행동은 λ¬΄μ—‡μž…λ‹ˆκΉŒ?
첫 번째 $onChanges ν˜ΈμΆœμ€ $onInit 호좜 전에 μˆ˜ν–‰λ©λ‹ˆλ‹€.
Angular 1.6 κΈ°λ³Έ ꡬ성(사전 ν• λ‹Ή = false)을 μ‚¬μš©ν•˜λ©΄ μƒμ„±μžμ—μ„œ 바인딩에 아직 μ•‘μ„ΈμŠ€ν•  수 μ—†λŠ” 경우 $onInit ν•¨μˆ˜μ—μ„œ 컨트둀러 μƒνƒœλ₯Ό μ΄ˆκΈ°ν™”ν•˜λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€.

μ˜ˆμƒλ˜λŠ” λ™μž‘μ€ λ¬΄μ—‡μž…λ‹ˆκΉŒ?
$onInit λ¨Όμ € ν˜ΈμΆœν•˜λŠ” 것이 더 논리적이라고 μƒκ°ν•©λ‹ˆλ‹€.
AngularλŠ” μ»¨νŠΈλ‘€λŸ¬κ°€ μ™„μ „νžˆ μ΄ˆκΈ°ν™”λ˜μ§€ μ•Šμ€ λ™μ•ˆμ—λŠ” 아무 것도 ν•΄μ„œλŠ” μ•ˆ λ©λ‹ˆλ‹€.

행동을 λ°”κΎΈλŠ” 동기/μ‚¬μš© μ‚¬λ‘€λŠ” λ¬΄μ—‡μž…λ‹ˆκΉŒ?
μš°λ¦¬λŠ” λ§Œλ“€ 수 ν•΄μ•Όν•˜λŠ” 개체λ₯Ό μ‚¬μš©ν•˜λŠ” 경우 $onInit ν•¨μˆ˜ $onChanges κΈ°λŠ₯을; μ»¨νŠΈλ‘€λŸ¬κ°€ 아직 μ΄ˆκΈ°ν™”λ˜μ§€ μ•Šμ•˜κΈ° λ•Œλ¬Έμ— 첫 번째 ν˜ΈμΆœμ—μ„œ 였λ₯˜κ°€ λ°œμƒν•©λ‹ˆλ‹€.
해결책은 μƒμ„±μž λ‚΄μ—μ„œ ν•΄λ‹Ή 객체λ₯Ό μ΄ˆκΈ°ν™”ν•˜λŠ” κ²ƒμ΄μ§€λ§Œ 컨트둀러λ₯Ό 두 κ³³μ—μ„œ μ΄ˆκΈ°ν™”ν•  κ²ƒμž…λ‹ˆλ‹€...

μ–΄λ–€ λ²„μ „μ˜ Angular와 μ–΄λ–€ λΈŒλΌμš°μ €/OSκ°€ 이 문제의 영ν–₯을 λ°›μŠ΅λ‹ˆκΉŒ? λ˜ν•œ μ΅œμ‹  μ•ˆμ • 및 μŠ€λƒ…μƒ·(https://code.angularjs.org/snapshot/) λ²„μ „μœΌλ‘œ ν…ŒμŠ€νŠΈν•˜μ‹­μ‹œμ˜€.
μ•΅κ·€λŸ¬ 1.6 버전

works as expected

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

이것은 μ˜λ„λœ κ²ƒμž…λ‹ˆλ‹€(주둜 Angular 2+ λ™μž‘κ³Ό μΌμΉ˜μ‹œν‚€κΈ° μœ„ν•¨). λ†“μΉœ 경우 $onChanges 의 isFirstChange() λ©”μ„œλ“œμ˜ λ°˜ν™˜ 값을 ν™•μΈν•˜μ—¬ $onChanges 의 첫 번째($onInit 이전) ν˜ΈμΆœμΈμ§€ 확인할 수 μžˆμŠ΅λ‹ˆλ‹€ SimpleChange 개체:

{
  ...
  bindings: {foo: '<'},
  controller: function SomeController() {
    this.$onChanges = function(changes) {
      if (changes.foo.isFirstChange()) {
        // `$onInit()` has not been called yet...
      }
    };
  }
}

#

λ‚˜λŠ” λ‚˜μ˜ 첫 λ°˜μ‘μ΄ λ˜‘κ°™μ•˜λ‹€λŠ” 것을 μΈμ •ν•œλ‹€. λ©˜νƒˆ λͺ¨λΈμ˜ κ΄€μ μ—μ„œ 보면 $onInit() κ°€ μ»¨νŠΈλ‘€λŸ¬μ—μ„œ κ°€μž₯ λ¨Όμ € μΌμ–΄λ‚˜λŠ” 일이라고 μƒκ°ν•˜λŠ” 것이 더 μ‰½μŠ΅λ‹ˆλ‹€. $onChanges() , $onChanges() , $onChanges() 그리고 λ§ˆμ§€λ§‰μœΌλ‘œ $onDestroy() .

ν•˜μ§€λ§Œ 생각해보면 $onInit λ₯Ό ν˜ΈμΆœν•˜κΈ° 전에 바인딩을 ν‰κ°€ν•˜κ³  컨트둀러 μΈμŠ€ν„΄μŠ€μ— ν• λ‹Ήν•΄μ•Ό ν•©λ‹ˆλ‹€. 그리고 κ·Έλ ‡κ²Œ ν•¨μœΌλ‘œμ¨ (이전에 μ •μ˜λ˜μ§€ μ•Šμ€) κ°’μ˜ 변경이 κ°μ§€λ˜κ³ , $onChanges λ₯Ό 톡해 λ³΄κ³ λ˜μ–΄μ•Ό ν•©λ‹ˆλ‹€.

λ‹«λŠ” μ€‘μž…λ‹ˆλ‹€. μ˜ˆμƒλŒ€λ‘œ(λ˜λŠ” μ΅œμ†Œν•œ μ˜λ„ν•œ λŒ€λ‘œ :wink:) μž‘λ™ν•˜κΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€.

λͺ¨λ“  9 λŒ“κΈ€

이것은 μ˜λ„λœ κ²ƒμž…λ‹ˆλ‹€(주둜 Angular 2+ λ™μž‘κ³Ό μΌμΉ˜μ‹œν‚€κΈ° μœ„ν•¨). λ†“μΉœ 경우 $onChanges 의 isFirstChange() λ©”μ„œλ“œμ˜ λ°˜ν™˜ 값을 ν™•μΈν•˜μ—¬ $onChanges 의 첫 번째($onInit 이전) ν˜ΈμΆœμΈμ§€ 확인할 수 μžˆμŠ΅λ‹ˆλ‹€ SimpleChange 개체:

{
  ...
  bindings: {foo: '<'},
  controller: function SomeController() {
    this.$onChanges = function(changes) {
      if (changes.foo.isFirstChange()) {
        // `$onInit()` has not been called yet...
      }
    };
  }
}

#

λ‚˜λŠ” λ‚˜μ˜ 첫 λ°˜μ‘μ΄ λ˜‘κ°™μ•˜λ‹€λŠ” 것을 μΈμ •ν•œλ‹€. λ©˜νƒˆ λͺ¨λΈμ˜ κ΄€μ μ—μ„œ 보면 $onInit() κ°€ μ»¨νŠΈλ‘€λŸ¬μ—μ„œ κ°€μž₯ λ¨Όμ € μΌμ–΄λ‚˜λŠ” 일이라고 μƒκ°ν•˜λŠ” 것이 더 μ‰½μŠ΅λ‹ˆλ‹€. $onChanges() , $onChanges() , $onChanges() 그리고 λ§ˆμ§€λ§‰μœΌλ‘œ $onDestroy() .

ν•˜μ§€λ§Œ 생각해보면 $onInit λ₯Ό ν˜ΈμΆœν•˜κΈ° 전에 바인딩을 ν‰κ°€ν•˜κ³  컨트둀러 μΈμŠ€ν„΄μŠ€μ— ν• λ‹Ήν•΄μ•Ό ν•©λ‹ˆλ‹€. 그리고 κ·Έλ ‡κ²Œ ν•¨μœΌλ‘œμ¨ (이전에 μ •μ˜λ˜μ§€ μ•Šμ€) κ°’μ˜ 변경이 κ°μ§€λ˜κ³ , $onChanges λ₯Ό 톡해 λ³΄κ³ λ˜μ–΄μ•Ό ν•©λ‹ˆλ‹€.

λ‹«λŠ” μ€‘μž…λ‹ˆλ‹€. μ˜ˆμƒλŒ€λ‘œ(λ˜λŠ” μ΅œμ†Œν•œ μ˜λ„ν•œ λŒ€λ‘œ :wink:) μž‘λ™ν•˜κΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€.

λ‹΅λ³€ν•΄ μ£Όμ…”μ„œ κ°μ‚¬ν•©λ‹ˆλ‹€. 이제 더 λͺ…ν™•ν•΄μ§‘λ‹ˆλ‹€. :)

λ‚˜λŠ” 이것이 μ˜λ„μ μ΄λΌλŠ” 것을 μ΄ν•΄ν•©λ‹ˆλ‹€. $onInit() 내뢀에 $onChanges() ν•¨μˆ˜μ˜ μ •μ˜λ₯Ό λ“±λ‘ν•˜λ©΄ μ–΄λ–»μŠ΅λ‹ˆκΉŒ?

@bharatpatil , AngularJS(1.x.)μ—μ„œλŠ” μž‘λ™ν•΄μ•Ό ν•˜μ§€λ§Œ Angular(2+)μ—μ„œλŠ” μž‘λ™ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

if (changes.foo.isFirstChange()) {
// $onInit() λŠ” 아직 ν˜ΈμΆœλ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€...
}

@gkalpak λ‚˜λŠ” 이 μ£Όμž₯이 ν‹€λ Έλ‹€κ³  μƒκ°ν•œλ‹€. binding.isFirstChange() λ©”μ„œλ“œλŠ” κ΄€λ ¨λœ 바인딩이 처음 ν˜ΈμΆœλ˜μ—ˆμŒμ„ 보μž₯ν•©λ‹ˆλ‹€. μ„œλΉ„μŠ€ 호좜 ν›„ μ΄ˆκΈ°ν™”λ˜λŠ” 바인딩은 μ‹œκ°„μ΄ λ„ˆλ¬΄ 였래 κ±Έλ¦°λ‹€κ³  μƒκ°ν•˜μ‹­μ‹œμ˜€. 이 경우 controller.$onInit 방법은 전에 호좜 ν•  ν•„μš”κ°€ controller.$onChanges 방법. λ‚΄κ°€ 잘λͺ»?

바인딩은 항상 μ‹œμž‘ 뢀뢄에 값을 가지며( undefined 일 수 있음) 이 값은 항상 사전 μ΄ˆκΈ°ν™”λœ κ°’κ³Ό λ‹€λ¦…λ‹ˆλ‹€. λ”°λΌμ„œ, $onChanges() 항상 ν˜ΈμΆœλ©λ‹ˆλ‹€ changes.foo ν˜ΈμΆœν•˜κΈ° 전에 $onInit() .

바인딩이 μ΄ˆκΈ°ν™” 되기 전에 값을 κ°€μ§ˆ 수 μžˆλ‹€λŠ” 것은 논리적이지 μ•ŠμŠ΅λ‹ˆλ‹€. 이것이 initialise(μ΄ˆκΈ°κ°’ μ„€μ •)λΌλŠ” λ‹¨μ–΄μ˜ 사전 μ •μ˜μž…λ‹ˆλ‹€. 초기 값이 μ—†μœΌλ©΄ λ³€κ²½ν•  수 μ—†μŠ΅λ‹ˆλ‹€. μ—¬κΈ° 넀이밍이 λ‹€ 틀리고 λΆ€μžμ—°μŠ€λŸ½λ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€.

λ‹€μŒ μ½”λ“œμ™€ 같은 것을 μž‘μ„±ν•˜λ„λ‘ κ°•μš”λ°›μ§€ μ•Šμ€ 상황을 κΈ°μ–΅ν•  수 μ—†μŠ΅λ‹ˆλ‹€.

$onChanges(changesObj: { [index: string]: angular.IChangesObject; })  {
   if (!this.isInitialized) return;
   ...
}

"μ΄ˆκΈ°ν™”" 전에 "λ³€κ²½"을 ν˜ΈμΆœν•˜λŠ” 것은 μ˜λ―Έκ°€ μ—†μŠ΅λ‹ˆλ‹€.

Angularλ₯Ό μ‚¬μš©ν•˜λŠ” 과정에 λŒ€ν•œ 평가 ... λ³€κ²½ 전에 μ΄ˆκΈ°ν™”κ°€ λ°œμƒν•  κ²ƒμœΌλ‘œ μ˜ˆμƒν•˜λŠ” μ΄μœ λŠ” λ¬΄μ—‡μž…λ‹ˆκΉŒ?

이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰