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
경고 다음은 setter것 NOT (즉, 등, 어레이에 밀어 목적 돌연변이) 참조에 의해 전달되는 값에 의해 돌연변이 유발한다. 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.