From 228296cb07edc4f7708c62090ff7dd7c08a82846 Mon Sep 17 00:00:00 2001 From: dhilt Date: Thu, 12 Dec 2019 00:53:17 +0300 Subject: [PATCH 1/6] table layout dev --- demo/app/samples/test.component.html | 34 +++++++++++++++++----------- demo/styles.css | 17 ++++++++++++++ src/component/classes/viewport.ts | 10 ++++++-- src/component/processes/render.ts | 8 ++++++- src/ui-scroll.component.ts | 28 ++++++++++++++++++----- src/ui-scroll.directive.ts | 6 +++++ 6 files changed, 81 insertions(+), 22 deletions(-) diff --git a/demo/app/samples/test.component.html b/demo/app/samples/test.component.html index a5aa48ce..6e1753e3 100644 --- a/demo/app/samples/test.component.html +++ b/demo/app/samples/test.component.html @@ -41,17 +41,25 @@

-
-
- - {{item.text}} - - {{item.isSelected ? '********' : ''}} - - -
+
+ + + + + + + +
data
+
+ + {{item.text}} + + {{item.isSelected ? '********' : ''}} + + +
+
diff --git a/demo/styles.css b/demo/styles.css index 72809079..2a1bcab0 100644 --- a/demo/styles.css +++ b/demo/styles.css @@ -318,3 +318,20 @@ li.L1,li.L3,li.L5,li.L7,li.L9 { } pre .typ, code .typ { font-weight: bold } pre .tag, code .tag { font-weight: bold; color: #204a87; } } + +table tr.temp { + color: red; + position: fixed; + left: -99999px; +} + +table, caption, tbody, tfoot, thead, tr, th, td { + padding: 0; +} + +.tableFixHead { overflow-y: auto; height: 100px; } +.tableFixHead thead th { position: sticky; top: 0; } + +/* Just common table stuff. Really. */ +table { border-collapse: collapse; } +th { background:#eee; } diff --git a/src/component/classes/viewport.ts b/src/component/classes/viewport.ts index db2c80a9..478c7e2f 100644 --- a/src/component/classes/viewport.ts +++ b/src/component/classes/viewport.ts @@ -36,9 +36,15 @@ export class Viewport { this.scrollEventElement = (this.element.ownerDocument); this.scrollable = this.scrollEventElement.scrollingElement; } else { - this.host = this.element.parentElement; + this.host = this.element.parentElement;//.parentElement.parentElement; + if (this.host) { + this.host = this.host.parentElement; + } + if (this.host) { + this.host = this.host.parentElement; + } this.scrollEventElement = this.host; - this.scrollable = this.element.parentElement; + this.scrollable = this.host; } this.paddings = new Paddings(this.element, this.routines, settings); diff --git a/src/component/processes/render.ts b/src/component/processes/render.ts index 63146aea..93710e71 100644 --- a/src/component/processes/render.ts +++ b/src/component/processes/render.ts @@ -8,13 +8,18 @@ export default class Render { scroller.logger.stat('before new items render'); scroller.innerLoopSubscriptions.push( scroller.bindData().subscribe(() => { + const elts = scroller.viewport.element.querySelectorAll(`tr:not([data-sid])`); + if (elts && elts.length && elts.length === scroller.state.fetch.items.length) { + elts.forEach((elt, index) => { + (elt).dataset['sid'] = scroller.state.fetch.items[index].nodeId; + }); if (Render.processElements(scroller)) { scroller.callWorkflow({ process: Process.render, status: ProcessStatus.next, payload: { noClip: scroller.state.clip.noClip } }); - } else { + } } else { scroller.callWorkflow({ process: Process.render, status: ProcessStatus.error, @@ -55,6 +60,7 @@ export default class Render { item.element = element; item.element.style.left = ''; item.element.style.position = ''; + item.element.classList.remove('temp'); item.invisible = false; item.setSize(); buffer.cache.add(item); diff --git a/src/ui-scroll.component.ts b/src/ui-scroll.component.ts index 1157e0c3..b7d68573 100644 --- a/src/ui-scroll.component.ts +++ b/src/ui-scroll.component.ts @@ -9,11 +9,20 @@ import { Datasource as IDatasource } from './component/interfaces/index'; import { Datasource } from './component/classes/datasource'; import { Item } from './component/classes/item'; -/* tslint:disable:component-selector */ -@Component({ - selector: '[ui-scroll]', - changeDetection: ChangeDetectionStrategy.OnPush, - template: `
+
+ +
+
` +>
` + +/* tslint:disable:component-selector */ +@Component({ + selector: 'tbody [ui-scroll]', + changeDetection: ChangeDetectionStrategy.OnPush, + template }) export class UiScrollComponent implements OnInit, OnDestroy { @@ -34,6 +49,7 @@ export class UiScrollComponent implements OnInit, OnDestroy { public version: string; public template: TemplateRef; public datasource: IDatasource | Datasource; + public isTable: boolean; // use in the template public items: Array; diff --git a/src/ui-scroll.directive.ts b/src/ui-scroll.directive.ts index 81802f15..8b9766d1 100644 --- a/src/ui-scroll.directive.ts +++ b/src/ui-scroll.directive.ts @@ -8,6 +8,7 @@ import { Datasource } from './component/interfaces/datasource'; export class UiScrollDirective implements OnInit { private version: string; private datasource: Datasource; + private isTable: boolean; constructor( private templateRef: TemplateRef, @@ -20,6 +21,10 @@ export class UiScrollDirective implements OnInit { this.datasource = datasource; } + @Input() set uiScrollTable(value: any) { + this.isTable = !!value; + } + ngOnInit() { const templateView = this.templateRef.createEmbeddedView({}); const compFactory = this.resolver.resolveComponentFactory(UiScrollComponent); @@ -28,6 +33,7 @@ export class UiScrollDirective implements OnInit { ); componentRef.instance.datasource = this.datasource; componentRef.instance.template = this.templateRef; + componentRef.instance.isTable = this.isTable; componentRef.instance.version = version; } } From e38ad82856ea97e31c685df42e84b78ecc7b7cc3 Mon Sep 17 00:00:00 2001 From: Mark Dinh Date: Wed, 26 Feb 2020 11:24:52 +0000 Subject: [PATCH 2/6] Remove intermediate
wrapping tag for ui-scroll component by directly creating embedded view from component's template. --- src/ui-scroll.component.ts | 10 +++++++--- src/ui-scroll.directive.ts | 7 +++---- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/ui-scroll.component.ts b/src/ui-scroll.component.ts index b7d68573..c4fcb810 100644 --- a/src/ui-scroll.component.ts +++ b/src/ui-scroll.component.ts @@ -1,7 +1,8 @@ import { Component, OnInit, OnDestroy, TemplateRef, ElementRef, - ChangeDetectionStrategy, ChangeDetectorRef + ChangeDetectionStrategy, ChangeDetectorRef, + ViewChild } from '@angular/core'; import { Workflow } from './component/workflow'; @@ -9,7 +10,7 @@ import { Datasource as IDatasource } from './component/interfaces/index'; import { Datasource } from './component/classes/datasource'; import { Item } from './component/classes/item'; -const template = ` +const template = `
odd: item.$index % 2, even: !(item.$index % 2) }" ->
` +>
`; /* tslint:disable:component-selector */ @Component({ @@ -45,6 +46,9 @@ const template = ` }) export class UiScrollComponent implements OnInit, OnDestroy { + @ViewChild('uiScrollTemplateRef', { static: true }) + public uiScrollTemplateRef: TemplateRef; + // come from the directive public version: string; public template: TemplateRef; diff --git a/src/ui-scroll.directive.ts b/src/ui-scroll.directive.ts index 8b9766d1..649bbc88 100644 --- a/src/ui-scroll.directive.ts +++ b/src/ui-scroll.directive.ts @@ -26,14 +26,13 @@ export class UiScrollDirective implements OnInit { } ngOnInit() { - const templateView = this.templateRef.createEmbeddedView({}); const compFactory = this.resolver.resolveComponentFactory(UiScrollComponent); - const componentRef = this.viewContainer.createComponent( - compFactory, undefined, this.viewContainer.injector, [templateView.rootNodes] - ); + const componentRef = compFactory.create(this.viewContainer.injector); componentRef.instance.datasource = this.datasource; componentRef.instance.template = this.templateRef; componentRef.instance.isTable = this.isTable; componentRef.instance.version = version; + + this.viewContainer.createEmbeddedView(componentRef.instance.uiScrollTemplateRef); } } From 928a285751171a4547ada708cbd147c29a867133 Mon Sep 17 00:00:00 2001 From: dhilt Date: Thu, 27 Feb 2020 00:02:31 +0300 Subject: [PATCH 3/6] ng-template fix --- src/ui-scroll.component.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/ui-scroll.component.ts b/src/ui-scroll.component.ts index b837f558..0149d7b4 100644 --- a/src/ui-scroll.component.ts +++ b/src/ui-scroll.component.ts @@ -11,7 +11,7 @@ import { Datasource } from './component/classes/datasource'; import { Item } from './component/classes/item'; const tableTemplate = ` - +
@@ -55,7 +55,10 @@ const commonTemplate = ` @Component({ selector: 'tbody [ui-scroll]', changeDetection: ChangeDetectionStrategy.OnPush, - template: commonTemplate + tableTemplate + template: ` + ${commonTemplate} + ${tableTemplate} + ` }) export class UiScrollComponent implements OnInit, OnDestroy { From 12222adcc76d2caf0f8c5c4a3981a60d71da60d5 Mon Sep 17 00:00:00 2001 From: dhilt Date: Thu, 27 Feb 2020 00:42:34 +0300 Subject: [PATCH 4/6] pass parent element from directive + ngOnInit fake call --- demo/app/samples/test.component.html | 2 +- src/ui-scroll.component.ts | 8 ++++++-- src/ui-scroll.directive.ts | 1 + 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/demo/app/samples/test.component.html b/demo/app/samples/test.component.html index 6e1753e3..072994ac 100644 --- a/demo/app/samples/test.component.html +++ b/demo/app/samples/test.component.html @@ -46,7 +46,7 @@ data diff --git a/src/ui-scroll.component.ts b/src/ui-scroll.component.ts index 0149d7b4..c5ccda8e 100644 --- a/src/ui-scroll.component.ts +++ b/src/ui-scroll.component.ts @@ -70,6 +70,7 @@ export class UiScrollComponent implements OnInit, OnDestroy { public template: TemplateRef; public datasource: IDatasource | Datasource; public isTable: boolean; + public parentElement: HTMLElement; // use in the template public items: Item[] = []; @@ -79,11 +80,14 @@ export class UiScrollComponent implements OnInit, OnDestroy { constructor( public changeDetector: ChangeDetectorRef, - public elementRef: ElementRef) { } + public elementRef: ElementRef + ) { + setTimeout(() => this.ngOnInit()); // 😢 + } ngOnInit() { this.workflow = new Workflow( - this.elementRef.nativeElement, + this.parentElement, // this.elementRef.nativeElement, this.datasource, this.version, (items: Item[]) => { diff --git a/src/ui-scroll.directive.ts b/src/ui-scroll.directive.ts index 7d7e84db..60a58362 100644 --- a/src/ui-scroll.directive.ts +++ b/src/ui-scroll.directive.ts @@ -32,6 +32,7 @@ export class UiScrollDirective implements OnInit { componentRef.instance.template = this.templateRef; componentRef.instance.isTable = this.isTable; componentRef.instance.version = version; + componentRef.instance.parentElement = this.templateRef.elementRef.nativeElement.parentElement; this.viewContainer.createEmbeddedView(componentRef.instance.uiScrollTemplateRef); } } From 86be8e46b1e0cec84677293d14d3e7d8b3346330 Mon Sep 17 00:00:00 2001 From: Mark Dinh Date: Thu, 27 Feb 2020 16:31:51 +0000 Subject: [PATCH 5/6] Explicitly invoke change detection after dynamically creating component and inputting values. --- src/ui-scroll.component.ts | 4 +--- src/ui-scroll.directive.ts | 1 + 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/ui-scroll.component.ts b/src/ui-scroll.component.ts index c5ccda8e..3bb4cfc8 100644 --- a/src/ui-scroll.component.ts +++ b/src/ui-scroll.component.ts @@ -81,9 +81,7 @@ export class UiScrollComponent implements OnInit, OnDestroy { constructor( public changeDetector: ChangeDetectorRef, public elementRef: ElementRef - ) { - setTimeout(() => this.ngOnInit()); // 😢 - } + ) { } ngOnInit() { this.workflow = new Workflow( diff --git a/src/ui-scroll.directive.ts b/src/ui-scroll.directive.ts index 60a58362..f51ceba6 100644 --- a/src/ui-scroll.directive.ts +++ b/src/ui-scroll.directive.ts @@ -34,5 +34,6 @@ export class UiScrollDirective implements OnInit { componentRef.instance.version = version; componentRef.instance.parentElement = this.templateRef.elementRef.nativeElement.parentElement; this.viewContainer.createEmbeddedView(componentRef.instance.uiScrollTemplateRef); + componentRef.changeDetectorRef.detectChanges(); } } From 467a7e2076cdde1bedcd5ee5cd4216bc5ac1cf08 Mon Sep 17 00:00:00 2001 From: dhilt Date: Fri, 28 Feb 2020 02:32:26 +0300 Subject: [PATCH 6/6] delayed change detection: the workflow must be initialized after first render --- src/component/classes/viewport.ts | 12 +++--------- src/ui-scroll.directive.ts | 2 +- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/component/classes/viewport.ts b/src/component/classes/viewport.ts index 6d57ce4b..4c58663b 100644 --- a/src/component/classes/viewport.ts +++ b/src/component/classes/viewport.ts @@ -34,15 +34,9 @@ export class Viewport { this.scrollEventElement = (this.element.ownerDocument); this.scrollable = this.scrollEventElement.scrollingElement; } else { - this.host = this.element.parentElement; // .parentElement.parentElement; - if (this.host) { - this.host = this.host.parentElement; - } - if (this.host) { - this.host = this.host.parentElement; - } - this.scrollEventElement = this.host; - this.scrollable = this.host; + this.host = this.element.parentElement; + this.scrollEventElement = this.host.parentElement; + this.scrollable = this.host.parentElement; } this.paddings = new Paddings(this.element, this.routines, settings); diff --git a/src/ui-scroll.directive.ts b/src/ui-scroll.directive.ts index f51ceba6..41161ce3 100644 --- a/src/ui-scroll.directive.ts +++ b/src/ui-scroll.directive.ts @@ -34,6 +34,6 @@ export class UiScrollDirective implements OnInit { componentRef.instance.version = version; componentRef.instance.parentElement = this.templateRef.elementRef.nativeElement.parentElement; this.viewContainer.createEmbeddedView(componentRef.instance.uiScrollTemplateRef); - componentRef.changeDetectorRef.detectChanges(); + setTimeout(() => componentRef.changeDetectorRef.detectChanges()); // 😢 } }