import { cloneDeep } from 'lodash-es'; /* * @Author: 疯狂秀才(Lucas Huang) * @Date: 2019-06-16 13:44:59 * @LastEditors: 疯狂秀才(Lucas Huang) * @LastEditTime: 2019-08-15 09:47:34 * @QQ: 1055818239 * @Version: v0.0.1 */ import { BehaviorSubject, Observable } from 'rxjs'; import { Injectable } from '@angular/core'; import {merge} from 'lodash-es'; import { map } from 'rxjs/operators'; import { CommonUtils } from './../common.utils'; export interface RuntimeState { form?: { [key: string]: any}; model?: { [key: string]: any}; } const DefaultRuntimeState: RuntimeState = { form: {}, model: {} }; @Injectable({ providedIn: 'root' }) export class RuntimeStateService { private _state: RuntimeState; private stateSubject = new BehaviorSubject({}); state$: Observable = this.stateSubject.asObservable(); form$:Observable = this.state$.pipe( map((state: RuntimeState) => state.form)); lookupIsPending$: Observable = this.form$.pipe( map(f => f.lookup.pending) ); private _formState: any; private _lookupState: any; constructor(private utils: CommonUtils) { this._state = cloneDeep(DefaultRuntimeState); this._formState = this._state.form; this._lookupState = this._formState.lookup; } private setValue(newVal: { [key: string]: any }) { if (newVal) { this._state = merge(this._state, newVal); this.stateSubject.next(this._state); } } private getValue(keyPath: string) { return this.utils.getValue(keyPath, this._state); } destroy() { this._state = { form: {}, model: {} }; this._formState = this._state.form; this._lookupState = this._formState.lookup; this.stateSubject.next(this._state); } setLookupInstance(el: any) { this.setValue({form: { lookup: { instance: el }}}); } updateFormState(newVal: {[key: string]: any}) { this.setValue({ form: newVal }); } getFormState(keyPath: string) { return this.getValue('form.' + keyPath); } eventPath(evt: any) { const path = (evt.composedPath && evt.composedPath()) || evt.path, target = evt.target; if (path != null) { return (path.indexOf(window) < 0) ? path.concat(window) : path; } if (target === window) { return [window]; } const getParents = (node, memo = undefined) => { memo = memo || []; const parentNode = node.parentNode; if (!parentNode) { return memo; } else { return getParents(parentNode, memo.concat(parentNode)); } }; return [target].concat(getParents(target), window); } }