zent
Version:
一套前端设计语言和基于React的实现
150 lines (125 loc) • 3.25 kB
text/typescript
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<Value> implements IModel<Value> {
/**
* Model display name
*/
protected abstract _displayName: string;
/**
* @internal
*/
readonly validate$ = new Subject<IValidation>();
/**
* @internal
*
* 校验规则数组
*/
validators: IValidators<Value> = [];
/**
* @internal
*
* 初始值
*/
initialValue: Maybe<Value> = None();
/**
* 组件 unmount 的时候删除 model
*/
destroyOnUnmount = false;
private subscriptions: Subscription[] = [];
abstract owner: IModel<any> | null;
/** @internal */
[MODEL_ID]!: boolean;
abstract getRawValue(): Value;
abstract getSubmitValue(): any;
readonly error$ = new BehaviorSubject<IMaybeError<Value>>(null);
abstract get valid$(): BehaviorSubject<boolean>;
abstract get value$(): BehaviorSubject<Value>;
/**
* @internal
*
* Same as value$ but without warning, internal code should use this method
*/
abstract _getValue$(shouldWarn?: boolean): BehaviorSubject<Value>;
/**
* @internal
*
* Same as valid$ but without warning, internal code should use this method
*/
abstract _getValid$(shouldWarn?: boolean): BehaviorSubject<boolean>;
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<any>;
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<IMaybeError<Value>>((resolve, reject) => {
this.validate$.next({
option,
resolve,
reject,
});
});
}
/**
* 获取 model 上的错误信息
*/
get error() {
return this.error$.getValue();
}
/**
* 设置 model 上的错误信息
*/
set error(error: IMaybeError<Value>) {
this.error$.next(error);
}
}
BasicModel.prototype[MODEL_ID] = true;
export { BasicModel };