|
@@ -0,0 +1,221 @@
|
|
|
+import { ListView } from 'antd-mobile';
|
|
|
+
|
|
|
+const getSectionData = (dataBlob, sectionID) => dataBlob[sectionID];
|
|
|
+const getRowData = (dataBlob, sectionID, rowID) => dataBlob[rowID];
|
|
|
+export const NewDataSource = function () {
|
|
|
+ return new ListView.DataSource({
|
|
|
+ getRowData,
|
|
|
+ getSectionHeaderData: getSectionData,
|
|
|
+ rowHasChanged: (row1, row2) => { return row1 !== row2; },
|
|
|
+ sectionHeaderHasChanged: (s1, s2) => s1 !== s2,
|
|
|
+ });
|
|
|
+};
|
|
|
+export const ListData = function (field = 'id') {
|
|
|
+ this.field = field;
|
|
|
+ this.maxSectionId = 0;
|
|
|
+ this.maxSectionId = 0;
|
|
|
+ this.loading = false;
|
|
|
+ this.bottom = false;
|
|
|
+ this.top = false;
|
|
|
+ this.dataSource = NewDataSource();
|
|
|
+ this.dataBlob = {};
|
|
|
+ this.sectionIDs = [];
|
|
|
+ this.rowIDs = [];
|
|
|
+ this.count = -1;
|
|
|
+ this.total = 0;
|
|
|
+ this.dataSource = NewDataSource().cloneWithRowsAndSections(this.dataBlob, this.sectionIDs, this.rowIDs);
|
|
|
+};
|
|
|
+
|
|
|
+ListData.prototype.refresh = function () {
|
|
|
+ this.sectionIDs = [];
|
|
|
+ this.rowIDs = [];
|
|
|
+ this.dataBlob = {};
|
|
|
+ this.maxSectionId = 0;
|
|
|
+ this.maxSectionId = 0;
|
|
|
+ this.loading = false;
|
|
|
+ this.bottom = false;
|
|
|
+ this.top = false;
|
|
|
+ this.count = 0;
|
|
|
+ this.total = 0;
|
|
|
+ this.dataSource = NewDataSource().cloneWithRowsAndSections(this.dataBlob, this.sectionIDs, this.rowIDs);
|
|
|
+};
|
|
|
+
|
|
|
+ListData.prototype.append = function (sectionId, data, preNumber) {
|
|
|
+ const dataNum = data.length;
|
|
|
+ const ids = [];
|
|
|
+ for (let i = 0; i < dataNum; i += 1) {
|
|
|
+ const item = data[i];
|
|
|
+ const id = `${sectionId}:${item[this.field]}`;
|
|
|
+ this.dataBlob[id] = item;
|
|
|
+ ids.push(id);
|
|
|
+ }
|
|
|
+ const index = this.sectionIDs.indexOf(sectionId);
|
|
|
+ if (index >= 0) {
|
|
|
+ this.rowIDs[index] = ids.concat(this.rowIDs[index]);
|
|
|
+ } else {
|
|
|
+ this.sectionIDs = [sectionId].concat(this.sectionIDs);
|
|
|
+ this.rowIDs.unshift(ids);
|
|
|
+ }
|
|
|
+ this.rowIDs = [].concat(this.rowIDs);
|
|
|
+ this.dataSource = this.dataSource.cloneWithRowsAndSections(this.dataBlob, this.sectionIDs, this.rowIDs);
|
|
|
+ this.minSectionId = sectionId;
|
|
|
+ // console.log('append', data, preNumber)
|
|
|
+ if (dataNum < preNumber) {
|
|
|
+ this.top = true;
|
|
|
+ if (this.sectionIDs.length === 1) this.bottom = true;
|
|
|
+ }
|
|
|
+ this.count += dataNum;
|
|
|
+ this.loading = false;
|
|
|
+};
|
|
|
+ListData.prototype.push = function (sectionId, data, preNumber) {
|
|
|
+ // console.log('push', sectionId, data, preNumber)
|
|
|
+ const dataNum = data.length;
|
|
|
+ const ids = [];
|
|
|
+ for (let i = 0; i < dataNum; i += 1) {
|
|
|
+ const item = data[i];
|
|
|
+ const id = `${sectionId}:${item[this.field]}`;
|
|
|
+ this.dataBlob[id] = item;
|
|
|
+ ids.push(id);
|
|
|
+ }
|
|
|
+ const index = this.sectionIDs.indexOf(sectionId);
|
|
|
+ if (index >= 0) {
|
|
|
+ this.rowIDs[index] = this.rowIDs[index].concat(ids);
|
|
|
+ } else {
|
|
|
+ this.sectionIDs.push(sectionId);
|
|
|
+ this.rowIDs.push(ids);
|
|
|
+ this.sectionIDs = [].concat(this.sectionIDs);
|
|
|
+ }
|
|
|
+ this.rowIDs = [].concat(this.rowIDs);
|
|
|
+
|
|
|
+ this.dataSource = this.dataSource.cloneWithRowsAndSections(this.dataBlob, this.sectionIDs, this.rowIDs);
|
|
|
+ this.maxSectionId = sectionId;
|
|
|
+ if (dataNum < preNumber) {
|
|
|
+ this.bottom = true;
|
|
|
+ if (this.sectionIDs.length === 1) this.top = true;
|
|
|
+ }
|
|
|
+ this.count += dataNum;
|
|
|
+ this.loading = false;
|
|
|
+};
|
|
|
+ListData.prototype.pop = function () {
|
|
|
+ console.log('pop', this.sectionIDs.length);
|
|
|
+ if (this.sectionIDs.length === 0) return;
|
|
|
+ this.sectionIDs.pop();
|
|
|
+ this.sectionIDs = [].concat(this.sectionIDs);
|
|
|
+ const ids = this.rowIDs.pop();
|
|
|
+ ids.forEach((row) => { delete this.dataBlob[row]; });
|
|
|
+ this.dataSource = this.dataSource.cloneWithRowsAndSections(this.dataBlob, this.sectionIDs, this.rowIDs);
|
|
|
+ this.maxSectionId = this.sectionIDs[this.sectionIDs.length - 1];
|
|
|
+ this.bottom = false;
|
|
|
+ this.count -= ids.length;
|
|
|
+};
|
|
|
+ListData.prototype.shift = function () {
|
|
|
+ console.log('shift', this.sectionIDs.length);
|
|
|
+ if (this.sectionIDs.length === 0) return;
|
|
|
+ this.sectionIDs.pop();
|
|
|
+ this.sectionIDs = [].concat(this.sectionIDs);
|
|
|
+ const ids = this.rowIDs.pop();
|
|
|
+ ids.forEach((row) => { delete this.dataBlob[row]; });
|
|
|
+ this.dataSource = this.dataSource.cloneWithRowsAndSections(this.dataBlob, this.sectionIDs, this.rowIDs);
|
|
|
+ ([this.minSectionId] = this.sectionIDs);
|
|
|
+ this.top = false;
|
|
|
+ this.count -= ids.length;
|
|
|
+};
|
|
|
+ListData.prototype.get = function (sectionId, value, preNumber) {
|
|
|
+ this.total = value.total;
|
|
|
+ return this.push(sectionId, value.list, preNumber);
|
|
|
+};
|
|
|
+ListData.prototype.load = function () {
|
|
|
+ this.loading = true;
|
|
|
+};
|
|
|
+ListData.prototype.delete = function (sectionId, rowId) {
|
|
|
+ const index = this.sectionIDs.indexOf(sectionId);
|
|
|
+ if (index === -1) return;
|
|
|
+ this.rowIDs = [].concat(this.rowIDs);
|
|
|
+ this.rowIDs[index] = this.rowIDs[index].filter((row) => row !== rowId);
|
|
|
+ delete this.dataBlob[rowId];
|
|
|
+ this.dataSource = this.dataSource.cloneWithRowsAndSections(this.dataBlob, this.sectionIDs, this.rowIDs);
|
|
|
+ this.count -= 1;
|
|
|
+};
|
|
|
+ListData.prototype.update = function (sectionId, item) {
|
|
|
+ const index = this.sectionIDs.indexOf(sectionId);
|
|
|
+ if (index === -1) return;
|
|
|
+ const id = `${sectionId}:${item[this.field]}`;
|
|
|
+ const tmp = {};
|
|
|
+ Object.assign(tmp, item);
|
|
|
+ this.dataBlob[id] = tmp;
|
|
|
+ this.refresh();
|
|
|
+};
|
|
|
+ListData.prototype.addTop = function (value, preNumber) {
|
|
|
+ // console.log(value)
|
|
|
+ if (!value || value.length === 0) return [];
|
|
|
+ const sectionIds = [];
|
|
|
+ if (this.sectionIDs.length > 0) {
|
|
|
+ const index = 0;
|
|
|
+ const sectionId = this.sectionIDs[index];
|
|
|
+ const rowNumber = this.rowIDs[index].length;
|
|
|
+ if (rowNumber < preNumber) {
|
|
|
+ value.splice(0, preNumber - rowNumber).forEach((row) => {
|
|
|
+ const id = `${sectionId}:${row[this.field]}`;
|
|
|
+ this.rowIDs[index].push(id);
|
|
|
+
|
|
|
+ this.dataBlob[id] = row;
|
|
|
+ this.count += 1;
|
|
|
+ });
|
|
|
+ sectionIds.push(sectionId);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (value.length > 0) {
|
|
|
+ const ids = value.map(row => {
|
|
|
+ return row[this.field];
|
|
|
+ });
|
|
|
+ const maxSectionId = Math.max.apply(null, ids);
|
|
|
+ // console.log(ids, maxSectionId)
|
|
|
+ sectionIds.push(maxSectionId);
|
|
|
+ this.append(maxSectionId, value, preNumber);
|
|
|
+ } else {
|
|
|
+ this.rowIDs = [].concat(this.rowIDs);
|
|
|
+ this.dataSource = this.dataSource.cloneWithRowsAndSections(this.dataBlob, this.sectionIDs, this.rowIDs);
|
|
|
+ }
|
|
|
+ return sectionIds;
|
|
|
+};
|
|
|
+ListData.prototype.addBottom = function (value, preNumber) {
|
|
|
+ // console.log(value)
|
|
|
+ if (!value || value.length === 0) return [];
|
|
|
+ const sectionIds = [];
|
|
|
+ if (this.sectionIDs.length > 0) {
|
|
|
+ const index = this.sectionIDs.length - 1;
|
|
|
+ const sectionId = this.sectionIDs[index];
|
|
|
+ const rowNumber = this.rowIDs[index].length;
|
|
|
+ if (rowNumber < preNumber) {
|
|
|
+ value.splice(0, preNumber - rowNumber).forEach((row) => {
|
|
|
+ const id = `${sectionId}:${row[this.field]}`;
|
|
|
+ this.rowIDs[index].push(id);
|
|
|
+
|
|
|
+ this.dataBlob[id] = row;
|
|
|
+ this.count += 1;
|
|
|
+ });
|
|
|
+ sectionIds.push(sectionId);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (value.length > 0) {
|
|
|
+ const ids = value.map(row => {
|
|
|
+ return row[this.field];
|
|
|
+ });
|
|
|
+ const minSectionId = Math.min.apply(null, ids);
|
|
|
+ // console.log(ids, minSectionId)
|
|
|
+ sectionIds.push(minSectionId);
|
|
|
+ this.push(minSectionId, value, preNumber);
|
|
|
+ } else {
|
|
|
+ this.rowIDs = [].concat(this.rowIDs);
|
|
|
+ this.dataSource = this.dataSource.cloneWithRowsAndSections(this.dataBlob, this.sectionIDs, this.rowIDs);
|
|
|
+ }
|
|
|
+ return sectionIds;
|
|
|
+};
|
|
|
+ListData.prototype.refresh = function () {
|
|
|
+ this.dataSource = NewDataSource().cloneWithRowsAndSections(this.dataBlob, this.sectionIDs, this.rowIDs);
|
|
|
+};
|
|
|
+ListData.prototype.rowId = function (sectionId, item) {
|
|
|
+ return `${sectionId}:${item[this.field]}`;
|
|
|
+};
|
|
|
+
|
|
|
+export default ListData;
|