Skip to content

Instantly share code, notes, and snippets.

@zookatron
Created August 16, 2017 21:00
Show Gist options
  • Save zookatron/2acafed1dac1a8e6b7c503f8a47cbe4f to your computer and use it in GitHub Desktop.
Save zookatron/2acafed1dac1a8e6b7c503f8a47cbe4f to your computer and use it in GitHub Desktop.
Angular Input decorator that produces an Observable
import { Input } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
/*
* Declares a reactively data-bound input property.
*
* Angular automatically updates data-bound properties during change detection.
*
* `Input` takes an optional parameter that specifies the name
* used when instantiating a component in the template. When not provided,
* the name of the decorated property is used.
*
* ### Example
*
* The following example creates a component with two input properties.
*
* ```typescript
* @Component({
* selector: 'bank-account',
* template: `
* Bank Name: {{bankName}}
* Account Id: {{id}}
* `
* })
* class BankAccount {
* @ReactiveInput() bankName: Observable<string>;
* @ReactiveInput('account-id') id: Observable<string>;
*
* // this property is not bound, and won't be automatically updated by Angular
* normalizedBankName: string;
* }
*
* @Component({
* selector: 'app',
* template: `
* <bank-account bank-name="RBC" account-id="4747"></bank-account>
* `
* })
* class App {}
* ```
*/
export function ReactiveInput(key?: string): PropertyDecorator {
return (target: any, prop: string, descriptor?: PropertyDescriptor): PropertyDescriptor => {
let finalKey = key || prop;
Input(finalKey)(target, prop);
let dataKey = '__ReactiveInput'+finalKey;
let getData = (instance) => {
if(!instance.hasOwnProperty(dataKey)) {
Object.defineProperty(instance, dataKey, {value: new BehaviorSubject<any>(undefined)});
}
return instance[dataKey];
};
return _.assign(descriptor, {
get: function() { return getData(this).asObservable(); },
set: function(value) { return getData(this).next(value); },
});
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment