import { BehaviorSubject, Subject, Subscription } from 'rxjs'; import { ErrorSubscriber, IMaybeError, IValidation, IValidators, validate, ValidateOption, } from '../validate'; import { switchMap } from 'rxjs/operators'; import { Maybe, None } from '../maybe'; import { IModel } from './base'; import { MODEL_ID } from './is'; abstract class BasicModel implements IModel { /** * Model display name */ protected abstract _displayName: string; /** * @internal */ readonly validate$ = new Subject(); /** * @internal * * 校验规则数组 */ validators: IValidators = []; /** * @internal * * 初始值 */ initialValue: Maybe = None(); /** * 组件 unmount 的时候删除 model */ destroyOnUnmount = false; private subscriptions: Subscription[] = []; abstract owner: IModel | null; /** @internal */ [MODEL_ID]!: boolean; abstract getRawValue(): Value; abstract getSubmitValue(): any; readonly error$ = new BehaviorSubject>(null); abstract get valid$(): BehaviorSubject; abstract get value$(): BehaviorSubject; /** * @internal * * Same as value$ but without warning, internal code should use this method */ abstract _getValue$(shouldWarn?: boolean): BehaviorSubject; /** * @internal * * Same as valid$ but without warning, internal code should use this method */ abstract _getValid$(shouldWarn?: boolean): BehaviorSubject; get value() { return this._getValue$().value; } set value(value: Value) { this.patchValue(value); } get form() { return this.owner?.form; } protected constructor(readonly id: string) { this.subscriptions.push( this.validate$ .pipe(switchMap(validate(this))) .subscribe(new ErrorSubscriber(this)) ); } abstract pristine(): boolean; abstract touched(): boolean; abstract dirty(): boolean; abstract patchValue(value: Value): void; abstract reset(): void; abstract clear(): void; abstract clearError(): void; abstract initialize(value: Value): void; abstract validate(option?: ValidateOption): Promise; dispose() { this.subscriptions.forEach(subscription => subscription.unsubscribe()); this.subscriptions = []; this.owner = null; this.clear(); this.clearError(); } valid() { return this._getValid$().value; } protected triggerValidate(option: ValidateOption) { /** * FormModel的owner是它自身 */ if (this.owner !== this && !(option & ValidateOption.StopPropagation)) { const parentOption = option & ~ValidateOption.IncludeChildrenRecursively; this.owner?.validate(parentOption); } return new Promise>((resolve, reject) => { this.validate$.next({ option, resolve, reject, }); }); } /** * 获取 model 上的错误信息 */ get error() { return this.error$.getValue(); } /** * 设置 model 上的错误信息 */ set error(error: IMaybeError) { this.error$.next(error); } } BasicModel.prototype[MODEL_ID] = true; export { BasicModel };