1/* 2 * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved. 3 */ 4import { ObservedArray } from '../data/ObservedArray'; 5import { BaseState, ViewState } from './ViewState'; 6 7/** 8 * 9 * @param <VS> 页面状态 10 * @param <VD> 页面数据 11 */ 12export abstract class AbsBaseViewData<VS extends ViewState, VD> implements IDataSource { 13 14 private listeners: DataChangeListener[] = [] 15 /** 16 * view state 17 */ 18 private state: VS; 19 /** 20 * view live date list 21 */ 22 private liveData: ObservedArray<VD> = new ObservedArray<VD>(); 23 24 /** 25 * 构造函数 26 */ 27 protected constructor() { 28 this.state = this.initViewState(); 29 } 30 31 totalCount(): number { 32 return this.liveData.length 33 } 34 35 registerDataChangeListener(listener: DataChangeListener) { 36 if (this.listeners.indexOf(listener) < 0) { 37 this.listeners.push(listener) 38 } 39 } 40 41 unregisterDataChangeListener(listener: DataChangeListener): void { 42 const pos = this.listeners.indexOf(listener); 43 if (pos >= 0) { 44 this.listeners.splice(pos, 1) 45 } 46 } 47 48 public getData(index: number): VD { 49 return this.liveData[index] 50 } 51 52 private initViewState(): VS { 53 return this.createViewState(); 54 } 55 56 protected abstract createViewState(): VS; 57 58 public getState(): VS { 59 return this.state; 60 } 61 62 /** 63 * start loading 64 */ 65 public loading(): void { 66 if (this.isEmpty()) { 67 this.state?.setViewState(BaseState.LOADING); 68 } 69 } 70 71 public normal(newData: ObservedArray<VD>): void { 72 this.clear() 73 this.liveData.push(...newData); 74 this.notifyDataReload() 75 this.state.setViewState(BaseState.NORMAL); 76 } 77 78 /** 79 * finish loading without data 80 */ 81 public normalState(): void { 82 this.state?.setViewState(BaseState.NORMAL); 83 } 84 85 /** 86 * clear livedata 87 */ 88 public clear(): void { 89 this.liveData.splice(0, this.liveData?.length) 90 } 91 92 /** 93 * 获取列表数据,不可变 94 * 95 * @return 不可变列表数据,运行时放通,问题在开发阶段发现问题 96 */ 97 public getDataList(): ObservedArray<VD> { 98 return this.liveData; 99 } 100 101 /** 102 * 针对分页的数据,不要使用normal,直接使用append 103 * 104 * @param appendData 需要追加的数据 105 */ 106 public append(appendData: VD[]): void { 107 this.liveData.push(...appendData); 108 this.notifyDataReload() 109 this.state.setViewState(BaseState.NORMAL); 110 } 111 112 /** 113 * 针对分页的数据,不要使用normal,直接使用append 114 * @param index index 115 * @param appendData 需要追加的数据 116 */ 117 public appendByIndex(index: number, appendData: VD[]): void { 118 this.liveData.splice(index, 0, ...appendData); 119 this.notifyDataAdd(index); 120 this.notifyDataReload() 121 this.state.setViewState(BaseState.NORMAL); 122 } 123 124 /** 125 * finish loading without data (only one data) 126 * 127 * @param newData newData 128 */ 129 public appendSingle(newData: VD): void { 130 this.liveData.push(newData); 131 this.state.setViewState(BaseState.NORMAL); 132 } 133 134 /** 135 * 移除 136 * 137 * @param index 位置 138 */ 139 public remove(index: number): void { 140 this.liveData.splice(index, 1) 141 this.notifyDataDelete(index) 142 this.notifyDataReload() 143 } 144 145 /** 146 * 设置数据是否为空,涉及nodata页面展示 147 * 148 * @return 数据是否为空 149 */ 150 public isEmpty(): boolean { 151 return this.liveData.length === 0; 152 } 153 154 notifyDataReload(): void { 155 this.listeners.forEach(listener => { 156 listener.onDataReloaded() 157 }) 158 } 159 160 notifyDataAdd(index: number): void { 161 this.listeners.forEach(listener => { 162 listener.onDataAdd(index) 163 }) 164 } 165 166 notifyDataChange(index: number): void { 167 this.listeners.forEach(listener => { 168 listener.onDataChange(index) 169 }) 170 } 171 172 notifyDataDelete(index: number): void { 173 this.listeners.forEach(listener => { 174 listener.onDataDelete(index) 175 }) 176 } 177 178 notifyDataMove(from: number, to: number): void { 179 this.listeners.forEach(listener => { 180 listener.onDataMove(from, to) 181 }) 182 } 183}