Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/core/body/body.ctrl.d.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Model } from '../infrastructure/model';
import { Table } from '../dom/table';
import { ScrollService } from 'ng2-qgrid/core/scroll/scroll.service';

export declare class BodyCtrl {
constructor(model: Model, view: any, table: Table, bag: any);
constructor(model: Model, view: any, scrollService: ScrollService, table: Table, bag: any);

onScroll(e: any);
onWheel(e: any);
Expand Down
4 changes: 3 additions & 1 deletion src/core/body/body.ctrl.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ const VERTICAL_SCROLL_CLASS = `${GRID_PREFIX}-scroll-vertical`;
const HORIZONTAL_SCROLL_CLASS = `${GRID_PREFIX}-scroll-horizontal`;

export class BodyCtrl {
constructor(model, view, table, bag) {
constructor(model, view, scrollService, table, bag) {
this.model = model;
this.view = view;
this.scrollService = scrollService;
this.bag = bag;
this.table = table;
this.rangeStartCell = null;
Expand Down Expand Up @@ -131,6 +132,7 @@ export class BodyCtrl {
if (startCell && endCell) {
this.navigate(endCell);
this.view.selection.selectRange(startCell, endCell, 'body');
this.scrollService.scroll(e);
}
}
}
Expand Down
6 changes: 6 additions & 0 deletions src/core/scroll/scroll.service.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { Model } from '../infrastructure/model';
import { Table } from '../dom/table';

export declare class ScrollService {
constructor(model: Model, table: Table);
}
158 changes: 158 additions & 0 deletions src/core/scroll/scroll.service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
import { EventListener } from '../infrastructure/event.listener';
import { EventManager } from '../infrastructure/event.manager';
import { Disposable } from '../infrastructure/disposable';
import { AppError } from '../infrastructure/error';
import { jobLine } from '../services/job.line';

const OFFSET = 50;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add this properties under the scroll.model

const VELOCITY = 5;

export class ScrollService extends Disposable {
constructor(model, table) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

disposable service is not good practice, move all disposables outside of the service and body ctrl

super();

this.model = model;
this.table = table;
this.interval = null;
this.rect = null;
this.body = null;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use this.markup.body directly

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

markup is not available during the ScrollService initialization

this.job = jobLine(0);

const documentListener = new EventListener(document, new EventManager(this));
const windowListener = new EventListener(window, new EventManager(this));

this.using(documentListener.on('mouseup', () => {
if (this.interval) {
this.stop();
}
}));

this.using(windowListener.on('resize', () => {
this.setElementsState();
}));
}

canScroll(e) {
const table = this.rect;
Copy link
Collaborator

@klumba12 klumba12 Aug 6, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just call it rect: const {rect, offset} = this;


return !(e.clientY < (table.bottom - OFFSET) &&
e.clientY > (table.top + OFFSET) &&
e.clientX > (table.left + OFFSET) &&
e.clientX < (table.right - OFFSET))
}

scroll(e) {
if (!this.body) {
this.setElementsState();
}

if (this.interval) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how it could happen on start?

if (!this.canScroll(e)) {
this.stop();
return;
}
}

const direction = this.onEdgeOf(e);
if (direction && !this.interval) {
this.job(() => {
const interval = this.doScroll(direction);
this.interval = interval();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we emulate interval with jobs?

})
}

}

doScroll(direction) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rename to croll

const scrollState = this.model.scroll;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const {scroll} = this.model;

const scrolledToEnd = () => this.isScrolledToEnd(direction);

return () => setInterval(() => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

try to use job

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setInterval is located in function, which is already wrapped in Job.
image

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is to tricky, we need to make own interval like a jobLine, or emulate it with job

if (!scrolledToEnd()) {
switch (direction) {
case 'right':
case 'bottom': {
const course = direction === 'bottom' ? 'top' : 'left';
const origin = scrollState()[course];
scrollState({ [course]: origin + VELOCITY });
break;
}
case 'left':
case 'top': {
const course = direction === 'top' ? 'top' : 'left';
const origin = scrollState()[course];
scrollState({ [course]: origin - VELOCITY });
break;
}
default: {
throw new AppError('scroll.service', `doScroll: Wrong direction`);
}
}
}
}, VELOCITY);
}

isScrolledToEnd(direction) {
const body = this.body;

switch (direction) {
case 'top': {
return body.scrollTop === 0;
}
case 'bottom': {
return body.clientHeight === body.scrollHeight - body.scrollTop;
}
case 'left': {
return body.scrollLeft === 0;
}
case 'right': {
return body.scrollLeft === body.scrollWidth - body.clientWidth;
}
default: {
throw new AppError('scroll.service', `isScrolledToEnd: Wrong direction`);
}
}
}

onEdgeOf(e) {
const table = this.rect;

if (e.clientY < (table.top + OFFSET) &&
e.clientX > (table.left + OFFSET) &&
e.clientX < (table.right - OFFSET)) {
return 'top';
}

if (e.clientY > (table.bottom - OFFSET) &&
e.clientX > (table.left + OFFSET) &&
e.clientX < (table.right - OFFSET)) {
return 'bottom';
}

if (e.clientX < (table.left + OFFSET) &&
e.clientY > (table.top + OFFSET) &&
e.clientY < (table.bottom - OFFSET)) {
return 'left';
}

if (e.clientX > (table.right - OFFSET) &&
e.clientY > (table.top + OFFSET) &&
e.clientY < (table.bottom - OFFSET)) {
return 'right';
}

return false;
}

setElementsState() {
const view = this.table.view;

this.body = view.markup.body;
this.rect = view.rect(this.body);
}

stop() {
clearInterval(this.interval);
this.interval = null;
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Write unit tests

4 changes: 3 additions & 1 deletion src/lib/main/core/body/body-core.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { NgComponent } from '../../../infrastructure/component/ng.component';
import { RootService } from '../../../infrastructure/component/root.service';
import { ViewCoreService } from '../view/view-core.service';
import { TableCoreService } from '../table/table-core.service';
import { ScrollService } from 'ng2-qgrid/core/scroll/scroll.service';

@Component({
selector: 'tbody[q-grid-core-body]',
Expand Down Expand Up @@ -37,7 +38,8 @@ export class BodyCoreComponent extends NgComponent implements OnInit {

const { model } = this.root;
const table = this.$table;
const ctrl = new BodyCtrl(model, view, this.root.table, this.root.bag);
const scrollService = new ScrollService(model, this.root.table);
const ctrl = new BodyCtrl(model, view, scrollService, this.root.table, this.root.bag);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instantiate scrollService inside the BodyCtrl

const listener = new EventListener(element, new EventManager(this));

this.zone.runOutsideAngular(() => {
Expand Down