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