src/app/service/scroll.service.ts
プロパティ |
メソッド |
|
constructor(dataService: DataService, stateService: StateService)
|
|||||||||
Defined in src/app/service/scroll.service.ts:26
|
|||||||||
パラメータ :
|
checkEnd | ||||||
checkEnd(docs: any)
|
||||||
デコレータ :
@Catch()
|
||||||
Defined in src/app/service/scroll.service.ts:162
|
||||||
パラメータ :
戻り値 :
void
|
clearDoc |
clearDoc()
|
デコレータ :
@Catch()
|
Defined in src/app/service/scroll.service.ts:227
|
戻り値 :
void
|
Async createNextBuffer |
createNextBuffer()
|
デコレータ :
@Catch()
|
Defined in src/app/service/scroll.service.ts:207
|
戻り値 :
{}
|
Async init |
init()
|
デコレータ :
@Catch()
|
Defined in src/app/service/scroll.service.ts:51
|
戻り値 :
any
|
initScroll |
initScroll()
|
デコレータ :
@Catch()
|
Defined in src/app/service/scroll.service.ts:184
|
戻り値 :
void
|
move |
move(posY: number, wait: number, callback: any)
|
デコレータ :
@Catch()
|
Defined in src/app/service/scroll.service.ts:189
|
戻り値 :
void
|
Async prefetch |
prefetch()
|
デコレータ :
@Catch()
|
Defined in src/app/service/scroll.service.ts:38
|
戻り値 :
any
|
Async refreshBuffer |
refreshBuffer()
|
デコレータ :
@Catch()
|
Defined in src/app/service/scroll.service.ts:168
|
戻り値 :
{}
|
resize |
resize()
|
デコレータ :
@Catch()
|
Defined in src/app/service/scroll.service.ts:113
|
戻り値 :
void
|
Async setBuffer |
setBuffer()
|
デコレータ :
@Catch()
|
Defined in src/app/service/scroll.service.ts:88
|
戻り値 :
any
|
Private setConst |
setConst()
|
デコレータ :
@Catch()
|
Defined in src/app/service/scroll.service.ts:118
|
戻り値 :
void
|
stop |
stop()
|
Defined in src/app/service/scroll.service.ts:82
|
戻り値 :
void
|
update |
update()
|
デコレータ :
@Catch()
|
Defined in src/app/service/scroll.service.ts:130
|
戻り値 :
void
|
updatePos | ||||||
updatePos(docs: any[])
|
||||||
デコレータ :
@Catch()
|
||||||
Defined in src/app/service/scroll.service.ts:199
|
||||||
パラメータ :
戻り値 :
void
|
ADD_LOAD_SIZE |
Type : number
|
既定値 : 30
|
Defined in src/app/service/scroll.service.ts:12
|
CONTENTS_HEIGHT |
Defined in src/app/service/scroll.service.ts:15
|
docs |
Type : []
|
既定値 : []
|
Defined in src/app/service/scroll.service.ts:23
|
end |
Defined in src/app/service/scroll.service.ts:20
|
isEnd |
既定値 : false
|
Defined in src/app/service/scroll.service.ts:25
|
isWait |
既定値 : true
|
Defined in src/app/service/scroll.service.ts:10
|
nextDocs |
Type : []
|
既定値 : []
|
Defined in src/app/service/scroll.service.ts:24
|
pos |
Defined in src/app/service/scroll.service.ts:21
|
posY |
Defined in src/app/service/scroll.service.ts:22
|
PREFETCH_SIZE |
Type : number
|
既定値 : 10
|
Defined in src/app/service/scroll.service.ts:11
|
ROW_HEIGHT |
Type : number
|
既定値 : 169
|
Defined in src/app/service/scroll.service.ts:13
|
SCROLL_OFFSET |
Defined in src/app/service/scroll.service.ts:16
|
SCROLL_WAIT |
Type : number
|
既定値 : 100
|
Defined in src/app/service/scroll.service.ts:18
|
start |
Type : number
|
既定値 : 1
|
Defined in src/app/service/scroll.service.ts:19
|
state |
Defined in src/app/service/scroll.service.ts:26
|
THRESHOLD |
Defined in src/app/service/scroll.service.ts:17
|
WINDOW_HEIGHT |
Defined in src/app/service/scroll.service.ts:14
|
import {ElementRef, Injectable} from '@angular/core';
import {DataService} from './data.service';
import {MyEvent, StateService} from './state.service';
import {Catch} from '../class/log.class';
@Injectable()
export class ScrollService {
isWait = true;
PREFETCH_SIZE = 10;
ADD_LOAD_SIZE = 30;
ROW_HEIGHT = 169;
WINDOW_HEIGHT;
CONTENTS_HEIGHT;
SCROLL_OFFSET;
THRESHOLD;
SCROLL_WAIT = 100;//msec
start = 1;
end;
pos;
posY;
docs = [];
nextDocs = [];
isEnd = false;
state;
constructor(
private dataService: DataService,
private stateService: StateService,
) {
}
@Catch()
async prefetch() {
if (!this.stateService.state.setting.prefetch.value) return;
if (!this.PREFETCH_SIZE) return;
// try {
this.clearDoc();
this.docs = await this.dataService.getDocs({skip: 0, limit: this.PREFETCH_SIZE}) || [];
console.log('@@@ Prefetch完了');
// } catch (error) {
// throw new Error("" + error.message);
// }
}
@Catch()
async init() {
// try {
if (!this.stateService.state.setting.prefetch.value) {
this.clearDoc();
this.docs = await this.dataService.getDocs({
skip: 0,
limit: 2000
});
await this.initScroll();
this.isWait = true;
return;
}
if (this.PREFETCH_SIZE) {
await this.initScroll();
await this.setBuffer();
this.isWait = true;
} else {
this.clearDoc();
await this.setBuffer();
await this.initScroll();
this.isWait = true;
}
// this.stateService.publish(MyEvent.DB_UPDATE);
// } catch (error) {
// throw new Error("" + error.message);
// }
}
stop() {
this.isWait = true;
}
//初期バッファ設定
@Catch()
async setBuffer() {
this.setConst();
let query = {
skip: this.PREFETCH_SIZE,
limit: (this.ADD_LOAD_SIZE * 2 - this.PREFETCH_SIZE),
include_docs: true
};
let res = await this.dataService.getDocs(query);
this.docs = this.docs.concat(res).slice() || [];
if (this.docs && this.PREFETCH_SIZE) {
delete this.docs[this.docs.length - 1].isEnd;
}
// if (this.docs&&this.docs.length){
this.updatePos(this.docs);
this.checkEnd(this.docs);
this.isWait = false;
await this.createNextBuffer();
return;
// }
// throw new Error("No Data");
}
@Catch()
resize() {
this.setConst();
}
@Catch()
private setConst() {
//画面表示域の高さ
this.WINDOW_HEIGHT = innerHeight;
//リスト全体の高さ
this.CONTENTS_HEIGHT = this.ROW_HEIGHT * this.docs.length;
//スクロールオフセット
this.SCROLL_OFFSET = this.ROW_HEIGHT * this.ADD_LOAD_SIZE;
//データ追加ロードのしきい値
this.THRESHOLD = this.SCROLL_OFFSET / 2;
}
@Catch()
update() {
let posY = scrollY;
this.setConst();
//表示先頭のデータ番号
// this.pos = Math.floor(this.start + posY / this.ROW_HEIGHT);
// this.stateService.state.docCount = this.pos + "/" + this.stateService.state.docCount + "件目";
if (this.isWait || this.isEnd) {
// return;
}
//下スクロール可能サイズ
let bottomScrollMargin = this.CONTENTS_HEIGHT - this.WINDOW_HEIGHT - posY;
//log
console.log('posY=%d,magin=%d,threshold=%d,listH=%d',
posY, bottomScrollMargin, this.THRESHOLD, bottomScrollMargin + posY + this.WINDOW_HEIGHT);
//スクロール終端で強制反転
if (bottomScrollMargin < this.ROW_HEIGHT) {
console.log('スクロール強制反転');
this.move(scrollY - this.ROW_HEIGHT, 0, null);
}
//バッファのリフレッシュ
if (bottomScrollMargin < this.THRESHOLD) {
console.log('バッファ更新要求');
this.refreshBuffer();
}
}
@Catch()
checkEnd(docs: any) {
this.isEnd = docs.length < (this.ADD_LOAD_SIZE * 2);
this.isWait = this.isEnd;
}
@Catch()
async refreshBuffer() {
if (!this.nextDocs) {
return;
}
console.log('バッファ更新処理開始');
this.move(scrollY - this.SCROLL_OFFSET, this.SCROLL_WAIT, null);
this.docs = this.nextDocs || [];
this.updatePos(this.docs);
this.checkEnd(this.docs);
this.nextDocs = null;
console.log('バッファ更新完了:%d~%d件目', this.start, this.end);
await this.createNextBuffer();
return true;
}
@Catch()
initScroll() {
this.move(this.posY, this.SCROLL_WAIT, null);
}
@Catch()
move(posY: number, wait: number, callback: any) {
setTimeout(() => {
scroll(0, posY);
if (callback) {
callback();
}
}, wait);
}
@Catch()
updatePos(docs: any[]) {
this.start = docs[0].serial; //1から採番
this.end = this.start + (docs.length - 1);
this.pos = this.pos || 1;
this.posY = this.posY || 0;
}
@Catch()
async createNextBuffer() {
if (this.isEnd) {
return;
}
console.log('追加データ受信開始:%d~%d件目', this.end + 1, this.end + this.ADD_LOAD_SIZE);
let docs = await this.dataService.getDocs({
skip: this.end,
limit: this.ADD_LOAD_SIZE
});
if (!docs) {
return [];
}
this.nextDocs = this.docs.concat(docs).slice(this.ADD_LOAD_SIZE) || [];
console.log('次バッファ準備完了:%d~%d',
this.nextDocs[0].serial,
this.nextDocs[this.nextDocs.length - 1].serial);
}
@Catch()
clearDoc() {
this.docs = null;
this.nextDocs = null;
}
}