2017-01-29 13 views
1

かなり頻繁にコンポーネントの入力値のストリームを使用する必要があります。通常、私はこの方法でそれを実行します。角度2。入力デコレータの拡張

export class UserComponent { 
    userId$ = new BehaviorSubject<number>(null); 
    @Input() set userId(value: number) { 
     this.userId$.next(value); 
    } 
} 

が、私は疑問に思うInput$デコレータを作成する方法があります:

export class UserComponent { 
    @Input$() userId$ = new BehaviorSubject<number>(null); 
} 

答えて

2

はい、それは可能である、あなたがクラスフィールドに置き換えられます追加のデコレータを作成することができますが、 getter/setterペアの場合、getterはSubjectを返し、セッターはこのサブジェクトに対してnextを実行します。

AOTコンパイルが破損する可能性がありますのでご注意ください。

@Input() 
@Reactive(false) 
public subject:Subject<boolean>; //you don't even need to initialize 

export function Reactive(initialValue:any):Function 
{ 
    return function(target:Object, property:string) 
    { 
     const name:string = `__subject_${property}`; 

     Object.defineProperty(target, name, <PropertyDescriptor>{ 
      enumerable : false, 
      configurable: false, 
      writable : true 
     }); 

     Object.defineProperty(target, property, <PropertyDescriptor>{ 
      enumerable : true, 
      configurable: false, 
      get   : function():any 
      { 
       if(this[name] === undefined) 
       { 
        this[name] = new BehaviorSubject<any>(initialValue); 
       } 
       return this[name]; 
      }, 
      set   : function(val:any):void 
      { 
       if(this[name] === undefined) 
       { 
        this[name] = new BehaviorSubject<any>(initialValue); 
       } 
       this[name].next(val); 
      } 
     }); 
    } 
} 
+0

お世話になります。あなたは、AoTを破ると思うのはなぜですか? –

+0

タイプチェックはAOTモードではより厳しく、Subject フィールドに文字列値を割り当てようとすると失敗する可能性があります。互換性を保つために、既存のサブジェクトへの自動バインディング入力用のデコレータを作成することは理にかなっています。つまり、 '@Input()@Reactive (x => x.subject)bool:boolean;' – kemsky

+0

ありがとう –