Angular2 @ get / set 속성으로 입력


178

해당 구성 요소에 Angular2 구성 요소가 있습니다. 현재 해당 속성에 바인딩 할 수 있도록 @Input ()이 적용된 묶음 필드가 있습니다.

@Input() allowDay: boolean;

내가하고 싶은 것은 실제로 get / set을 사용하여 속성에 바인딩하여 setter에서 다음과 같은 다른 논리를 수행 할 수 있다는 것입니다.

_allowDay: boolean;
get allowDay(): boolean {
    return this._allowDay;
}
set allowDay(value: boolean) {
     this._allowDay = value;
     this.updatePeriodTypes();
}

Angular2에서 어떻게해야합니까?

Thierry Templier 제안에 따라 변경했지만 알려진 기본 속성이 아니기 때문에 'allowDay'에 바인딩 할 수 없다는 오류가 발생합니다.

//@Input() allowDay: boolean;
_allowDay: boolean;
get allowDay(): boolean {
    return this._allowDay;
}
@Input('allowDay') set allowDay(value: boolean) {
    this._allowDay = value;
    this.updatePeriodTypes();
}

[allowDay]="....". If the field (setter) name and the property name you want to use for binding are the same, you can omit the parameter for @Input (...)`에 바인딩하는 방법과 위치
Günter Zöchbauer

허용 된 답변에 표시된대로 get set 사용 경로를 사용하면 단위 테스트를 어떻게 설정했는지 궁금합니다.
Winnemucca

1
결국 무엇을 하든지 중단 점, 디버그 명령문 또는 카운터를 카운터 내부에 배치하여 예상대로 한 번만 발생하는지 확인하십시오. 방금 변경 변경 실행마다 끔찍한 성능과 기발한 동작을 유발하는 것으로 업데이트되었습니다.
Simon_Weaver

답변:


271

아래 설명에 따라 setter에서 @Input을 직접 설정할 수 있습니다.

_allowDay: boolean;
get allowDay(): boolean {
    return this._allowDay;
}

@Input('allowDay')
set allowDay(value: boolean) {
    this._allowDay = value;
    this.updatePeriodTypes();
}

이 plunkr 참조 https://plnkr.co/edit/6miSutgTe9sfEMCb8N4p?p=preview을 .


1
'allowDay'에 알려진 네이티브 속성이 아니기 때문에 다음 오류가 발생합니다. 코드를 정확히 변경 한 내용에 대한 업데이트 된 질문을 참조하십시오.
Paul Cavacas

확실합니까? 그것은 나를 위해 작동합니다. 나는 플런저를 추가했다. 아마도 당신이 directives그것을 사용하려는 구성 요소 의 속성에 지시문을 추가하는 것을 잊었을 것입니다 ... 나는 대답을 업데이트했습니다.
Thierry Templier

2
setter를 사용하면 ngOnChanges가 실행되지 않기 때문에 이것은 나쁜 생각입니다.
user2867288


11
경고 다음은 setterNOT (즉, 등, 어레이에 밀어 목적 돌연변이) 참조에 의해 전달되는 값에 의해 돌연변이 유발한다. to 트리거를 다시 전달하기 Input위해 전달되는 전체 값을 바꿔야 setter합니다.
Nickofthyme

61

주로 setter에 논리를 구현하는 데 관심이있는 경우 :

import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';

// [...]

export class MyClass implements OnChanges {
  @Input() allowDay: boolean;

  ngOnChanges(changes: SimpleChanges): void {
    if(changes['allowDay']) {
      this.updatePeriodTypes();
    }
  }
}

SimpleChanges입력 특성이 변경되었거나 중요하지 않은 입력 특성이있는 경우 가져 오기 가 필요하지 않습니다.

각도 문서 : OnChanges

그렇지 않으면:

private _allowDay: boolean;

@Input() set allowDay(value: boolean) {
  this._allowDay = value;
  this.updatePeriodTypes();
}
get allowDay(): boolean {
  // other logic
  return this._allowDay;
}

궁금한 점은 setter 논리에만 관심이 있다면 ngOnChanges를 사용하고 set 속성을 사용하지 않는 것의 이점이 있습니까?
Mese

4
"ngOnChanges를 사용하는 것과 set을 사용하지 않는 것"에는 차이가 없습니다 ...;) 농담 : 한 가지 장점은, 컴포넌트에 여러 @Input속성이 있고 어떤 것이 변경되었을 때 루틴을 호출하려는 경우입니다. 더 적은 코드가 필요합니다.
Martin Schneider

Ups, 오타가 있었다. 그러나 좋습니다. 더 관련성이 있다고 생각했습니다. 답변 tho :)
Mese

1
@ MA-Maddin 각기 일상적으로 실행해야하는 여러 변경 사항을 동시에 예상 할 경우 디 바운스 된 옵저버 블도 설정할 수 있다고 가정합니다.
Simon_Weaver

ngOnChanges 접근 방식이 훌륭합니다! 좋은 대답입니다. 설정중인 값이 개인용이 아닌 경우 (예 : 템플리트에서 바인딩으로 사용되는 경우) _propertyName setter / private 이름 지정 규칙이 일치하지 않습니다. ngOnChanges는이 문제를 완벽하게 해결합니다
Drenai

8

@Paul Cavacas, 나는 같은 문제가 있었고 Input()데코레이터를 게터 위에 설정하여 해결했습니다 .

  @Input('allowDays')
  get in(): any {
    return this._allowDays;
  }

  //@Input('allowDays')
  // not working
  set in(val) {
    console.log('allowDays = '+val);
    this._allowDays = val;
  }

이 플런저를보십시오 : https://plnkr.co/edit/6miSutgTe9sfEMCb8N4p?p=preview


6
이 버그는 저를 미치게 만들었습니다. 마침내 Input ()을 먼저 정의해야한다는 것을 알았습니다 (getter 또는 setter이지만 입력 데코레이터가 먼저 가야 함)
maxi-code


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.