import { ChangeDetectorRef } from '@angular/core'; import { ControlValueAccessor } from '@angular/forms'; import { Observable, Subject } from 'rxjs'; // tslint:disable-next-line:no-any type Constructor = new (...args: any[]) => T; // tslint:disable-next-line:no-any const noop: any = () => { // empty method }; export interface IControlValueAccessor extends ControlValueAccessor { /* tslint:disable-next-line */ value: any; // tslint:disable-next-line:no-any valueChanges: Observable; // tslint:disable-next-line:no-any onChange: (_: any) => any; // tslint:disable-next-line:no-any onTouched: () => any; } export interface IHasChangeDetectorRef { _changeDetectorRef: ChangeDetectorRef; } /** Mixin to augment a component with ngModel support. */ // tslint:disable-next-line:no-any export function mixinControlValueAccessor>(base: T, initialValue?: any): Constructor & T { return class extends base { // tslint:disable-next-line:no-any private _subjectValueChanges: Subject; // tslint:disable-next-line:no-any private _value: any = initialValue instanceof Array ? Object.assign([], initialValue) : initialValue; // tslint:disable-next-line:no-any valueChanges: Observable; // tslint:disable-next-line:no-any onChange = (_: any) => noop; onTouched = () => noop; // tslint:disable-next-line:no-any constructor(...args: any[]) { super(...args); /* tslint:disable-next-line */ this._subjectValueChanges = new Subject(); this.valueChanges = this._subjectValueChanges.asObservable(); } /* tslint:disable-next-line */ get value(): any { return this._value; } // tslint:disable-next-line:no-any set value(v: any) { if (v !== this._value) { this._value = v; this.onChange(v); this._changeDetectorRef.markForCheck(); this._subjectValueChanges.next(v); } } // tslint:disable-next-line:no-any writeValue(value: any): void { this.value = value; this._changeDetectorRef.markForCheck(); } // tslint:disable-next-line:no-any registerOnChange(fn: any): void { this.onChange = fn; } // tslint:disable-next-line:no-any registerOnTouched(fn: any): void { this.onTouched = fn; } }; }