/**
* 網路請求MVVM資料模型,由子類實現狀態機管理,由方法實現回撥監聽
*/
export abstract class LoadState {
/**
* loading函數,如果當前狀態是Loading,則呼叫回撥函數
* @param callBack 回撥函數
* @returns this
*/
loading(callBack?: () => void): this {
if (this instanceof Loading) {
callBack?.call(null);
}
return this;
}
/**
* loaded函數,如果當前狀態是Loaded,則呼叫回撥函數
* @param callBack 回撥函數
* @returns this
*/
loaded(callBack?: (result: Loaded<any>) => void): this {
if (this instanceof Loaded) {
callBack?.call(null, this);
}
return this;
}
/**
* loadError函數,如果當前狀態是LoadError,則呼叫回撥函數
* @param callBack 回撥函數
* @returns this
*/
loadError(callBack?: (error: LoadError) => void): this {
if (this instanceof LoadError) {
callBack?.call(null, this);
}
return this;
}
}
/**
* Loading類,繼承自LoadState類
*/
export class Loading extends LoadState {}
/**
* Loaded類,繼承自LoadState類,包含一個result屬性和一個data方法
*/
export class Loaded<T> extends LoadState {
result?: T;
constructor(data: T) {
super();
this.result = data;
}
data(): T | undefined {
return this.result;
}
}
/**
* LoadError類,繼承自LoadState類,包含code和message屬性
*/
export class LoadError extends LoadState {
code?: number;
message?: string;
constructor(code: number, message: string) {
super();
this.code = code;
this.message = message;
}
}
/**
* ValueNotifier類,包含_value、listeners屬性和addListener、notifyListeners、value方法
*/
export class ValueNotifier<T> {
private _value: T;
listeners: Array<() => void> = [];
constructor(value: T) {
this._value = value;
}
get value(): T {
return this._value;
}
set value(value: T) {
this._value = value;
this.notifyListeners();
}
addListener(listener: () => void) {
this.listeners.push(listener);
}
notifyListeners() {
for (let listener of this.listeners) {
listener();
}
}
}
以獲取一個車輛詳情的場景來模擬網路請求和資料處理
import { Loaded, LoadError, Loading, LoadState, ValueNotifier } from './LoadState';
export class VehicleViewModel {
lsVehicleDetail: ValueNotifier<LoadState | null>;
constructor() {
this.lsVehicleDetail = new ValueNotifier<LoadState | null>(null);
}
// 獲取車輛詳情
async getVehicleDetail() {
// 發起請求
this.lsVehicleDetail.value = new Loading();
await new Promise(resolve => setTimeout(resolve, 3000));
// 獲得資料
this.lsVehicleDetail.value = new Loaded("aa");
await new Promise(resolve => setTimeout(resolve, 3000));
// 模擬網路報錯
this.lsVehicleDetail.value = new LoadError(123, "error");
}
}
@Component
export struct VehicleComponent {
private vm: VehicleViewModel = new VehicleViewModel();
aboutToAppear() {
this.vm.lsVehicleDetail.addListener(() => {
this.vm.lsVehicleDetail.value?.loading(() => {
// 開始網路請求
console.log(`hello1:start Loading`);
}).loaded((result) => {
let data = result?.data() as String
console.log(`hello2:${result} - ${data}`);
}).loadError((error) => {
console.log(`hello3:${error?.code} - ${error?.message}`);
});
});
}
}
hello1:start Loading
hello2:[object Object] - aa
hello3:123 - error