Created
July 15, 2017 20:27
-
-
Save NetanelBasal/8f5dc9fe717929e75e344bf59a163c97 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Directive, ElementRef, forwardRef, Input, Renderer2 } from '@angular/core'; | |
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; | |
import { fromEvent } from 'rxjs/observable/fromEvent'; | |
import { merge } from 'rxjs/observable/merge'; | |
import { timer } from 'rxjs/observable/timer'; | |
import { Subscription } from 'rxjs/Subscription'; | |
export const DEFAULT_VALUE_ACCESSOR : any = { | |
provide: NG_VALUE_ACCESSOR, | |
useExisting: forwardRef(() => NgControlOptionsDirective), | |
multi: true | |
}; | |
@Directive({ | |
selector: 'input[type=text][formControlName][ngControlOptions],input[type=text][formControl][ngControlOptions]', | |
providers: [DEFAULT_VALUE_ACCESSOR] | |
}) | |
export class NgControlOptionsDirective implements ControlValueAccessor { | |
events : Subscription; | |
onChange; | |
onTouched; | |
registerOnChange( fn : any ) : void { | |
this.onChange = fn; | |
} | |
registerOnTouched( fn : any ) : void { | |
this.onTouched = fn; | |
} | |
constructor( private renderer : Renderer2, private element : ElementRef ) { | |
} | |
private _controlOptions = { | |
updateOn: 'input', | |
debounce: null | |
}; | |
@Input() set ngControlOptions( val ) { | |
this._controlOptions = { ...this._controlOptions, ...val }; | |
} | |
ngOnInit() { | |
const events = this._controlOptions.updateOn.split(' ').map(event => fromEvent(this.element.nativeElement, event)); | |
this.events = merge(...events) | |
.map(( e : Event ) => ( { type: e.type, value: e.target['value'] })) | |
.debounce(event => { | |
const debounceValue = this._controlOptions.debounce; | |
let time = 0; | |
if( typeof debounceValue === 'number' ) { | |
time = debounceValue; | |
} else if( typeof debounceValue === 'object' ) { | |
time = debounceValue[event.type] ? debounceValue[event.type] : 0; | |
} | |
return timer(time); | |
}) | |
.subscribe(event => { | |
this.onChange(event.value); | |
}); | |
// this.events = merge(...events) | |
// .map(( e : Event ) => ( {type: e.type, value: e.target[ 'value' ]})) | |
// .let(source => { | |
// if ( this._controlOptions.debounce ) { | |
// return source.debounce(event => { | |
// const time = ... | |
// return timer(time); | |
// }); | |
// } | |
// return source; | |
// }) | |
// .subscribe(event => { | |
// this.onChange(event.value); | |
// }); | |
} | |
writeValue( value : any ) : void { | |
const normalizedValue = value == null ? '' : value; | |
this.renderer.setProperty(this.element.nativeElement, 'value', normalizedValue); | |
} | |
setDisabledState( isDisabled : boolean ) : void { | |
this.renderer.setProperty(this.element.nativeElement, 'disabled', isDisabled); | |
} | |
ngOnDestroy() { | |
this.events.unsubscribe(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
awesome!