dinony / od-virtualscroll Goto Github PK
View Code? Open in Web Editor NEW🚀 Observable-based virtual scroll implementation in Angular
Home Page: https://dinony.github.io/od-vsstatic/
License: MIT License
🚀 Observable-based virtual scroll implementation in Angular
Home Page: https://dinony.github.io/od-vsstatic/
License: MIT License
Hi Dinony,
Do you plan horizontal scrolling?
Thanks for your cool library!
I tried to remove an item but it seems the actual item in the row does not get updated.
What is the correct way to remove an item so that the rows/items update accordingly?
The observer.next is the data$ which is bound to the od-virtualscroll component.
subs.push(this.removeItem$.subscribe((item: any) => {
const indexOfItemToRemove = curData.findIndex((i) => i.id === item.id);
let newData = [];
newData.push(...curData);
newData.splice(indexOfItemToRemove, 1);
this._curData = newData;
observer.next(newData);
}));
Just importing VirtualScrollModule
causes my otherwise AOT-compatible project to fail compilation with the error ERROR in Error encountered resolving symbol values statically. Calling function 'ɵmakeDecorator', function calls are not supported. Consider replacing the function or lambda with a reference to an exported function, resolving symbol Injectable in /node_modules/@angular/core/core.d.ts, resolving symbol ɵf in /node_modules/@angular/core/core.d.ts, resolving symbol ɵf in /node_modules/@angular/core/core.d.ts
.
It's possible that this is specific to only Angular 4.1 and/or TypeScript 2.3, as I haven't tested with any other versions of either of them.
Hi
I'm curious if this library is still being maintained and will be for the future?
Currently vsData
is expected to be Observable<any[]>
. It'd be useful if it were expanded to support the more general Observable<Iterable<any>>
, which would allow it to take such types as ES6 Maps and Sets and Immutable.js data structures.
I have a huge list of items displayed using the od-virtualscroll and it works great, the only thing i'm missing is implementing a search functionality.
I tried supplying a new Observable with the filtered values to the od-virtualscroll component but it's not working.
Should i combine the observable of values with a stream of filter values (using .combineLatest) and filter using .filter to feed the component vsData
?
Currently when options like item sizes are changed I have to somehow force the component to redraw. It seems that emitting the options itself is not enough to trigger any sort of redraw.
If I only emit options they seem to only take effect as I scroll through the items and the rows are updated.
For now I'm emitting an empty array and then right after that the data array, this seems to make it redraw but it feels messy.
subs.push(this.debounceResize$.subscribe(() => {
observer.next([]);
observer.next(curData);
}));
What is the intended initial scroll position intended to be? In my application, it seems to randomly alternate between starting at the top of the list and starting at the bottom of the list.
Could this setting be configurable? I have one use case where I would prefer to start at the top (contacts list) and another where I would want to start at the bottom (message history).
Upgrade to RxJs 6
I have a case where the component within the virtual scroll ng-template
needs to fetch some remote data before it will display anything. Specifically, ngOnInit
will fetch the data if it isn't already cached locally, and the top-level element of the component has something to the effect of *ngIf='valueObservable | async; let value'
.
However, when adding a lot of items at once and immediately scrolling to them, I'll see many gaps in the list that don't get filled until I scroll away and scroll back. Is there some kind of caching of DOM elements or something that could be causing this, or is it more likely a mistake on my end?
Ideally, this option would be able to make itemHeight
be treated as a static height for only off-screen items, with items in the viewport being rendered with their normal dynamic heights.
Alternatively, itemHeight
could be expanded to accept number|(item: any) => number
and/or each item could optionally include a property (something like odVirtualScrollHeight
) that would override the default itemHeight
for that particular item.
It would be really great to have an example / demo where flexLayout is used (e.g. responsive -> row based with wrap and a flex value which is based on the screen size).
e.g. code without od-virtualscroll
<div fxLayout="row" fxLayoutWrap="wrap">
<div fxFlex="25" fxFlex.md="33" fxFlex.sm="50" fxFlex.xs="100" *ngFor="let item of items" style="padding: 2px;">
<my-component [item]="item"></my-component>
</div>
</div>
I have not really an idea how to code something like this with od-virtualscroll....
I don't have an isolated test case right now, but in my project if the list gets resized for any reason (resizing the JS console, new element appearing underneath it, etc.), it locks the current viewport in place and virtual scrolling no longer works.
It's possible that this is related to Flexbox/flex-layout. This is the relevant section of the template where it's being triggered:
<div fxFlex fxLayout='row'>
<od-virtualscroll [vsData]='vsMessages' [vsOptions]='vsOptions'>
<ng-template let-item>
<cyph-chat-message
[message]='item'
[mobile]='mobile'
[unconfirmedMessages]='unconfirmedMessages'
></cyph-chat-message>
</ng-template>
</od-virtualscroll>
</div>
Also potentially relevant: od-virtualscroll doesn't seem to quite work with flex-layout directives (in particular fxFlex
and fxFlexFill
), so as a workaround I'm using the following CSS: od-virtualscroll, od-virtualrow { width: 100%; }
.
I created a post here : https://stackoverflow.com/questions/44819944/angular-4-observable-add-items
When I want to insert item in my list, it doesn't appear.
row items are not rendering in mobile devices. used in ionic 3 project. shows only numAdditionalRows items. not the calculated ones.
even on chrome browser debugging mode if we make the mobile screen mode and reload the page. list is loading only how many items we mentioned as numAdditionalRows.
I'm not sure if my code is doing something wrong, or maybe #16 caused a regression, but occasionally I'll have items get incorrectly positioned. My message "10" shows up in the DOM, but with an incorrect translateY
value that causes it to appear off-screen. Resizing the window and/or adding more list items sometimes fixes this.
re: #16, at one point I was able to reproduce something similar with the current master branch and static heights, such that there would be visibly overlapping items, so I think it probably isn't the root cause.
Here's a stackblitz that illustrates the issue. This just shows 60000 items. If you drag the scrollbar to the end, you should see Row: 59999 Item 59999. And it works fine in Chrome.
IE11 on the other hand, gets to about 30700 items when you get to the end, and that seems to be dependent on the size of the items.. I can use the scrollwheel, click on the up and down arrows, or grab the scroll thum and "drag" down on it -- though it does not move , of course -- to advance. But it should already be at the end.
Using chrome/firefox in Ubuntu 18.10 and macOSX (Mojave) at least two of the demo's have display issues which I opened here: dinony/od-vsadvanced#1
https://imgur.com/xSgu3vt
https://imgur.com/a/bELQIaF
The issue seems to come from the od-virtualrow elements, wrapping over to the next row (basically two rows then), which breaks the first few columns of the next row. It gets exaggerated when zooming in (page zoom)
Using FxFlex as I do through the rest of the app, but getting errors when used inside the virtualscroll component
Below is the markup, and the error
Another strange issue I'm seeing is that no matter what height i set the scroll container to, it is expanded to the length of every item and it doesnt virtually scroll at all but displays them all.
Would appreciate your feedback, thanks
<od-virtualscroll [vsData]="data" [vsOptions]="options" fxFlex="100" fxFill class="vscrollcontainer" style="background-color: red">
<ng-template let-item fxFlex="100">
<mat-card>
<app-date fxFill fxFlex="100" [date]="item" [showCancel]="false"></app-date>
</mat-card>
</ng-template>
</od-virtualscroll>
ERROR TypeError: Cannot set property '-webkit-flex' of undefined
at EmulatedEncapsulationDomRenderer2.DefaultDomRenderer2.setStyle (platform-browser.js:2924)
at BaseAnimationRenderer.setStyle (animations.js:590)
at DebugRenderer2.setStyle (core.js:15416)
at eval (flex-layout.es5.js:208)
at Array.forEach (<anonymous>)
at applyMultiValueStyleToElement (flex-layout.es5.js:204)
at applyStyleToElement (flex-layout.es5.js:179)
at FlexDirective.BaseFxDirective._applyStyleToElement (flex-layout.es5.js:699)
at FlexDirective._updateStyle (flex-layout.es5.js:2836)
at FlexDirective._onLayoutChange (flex-layout.es5.js:2823)
Kind of at a loss at this point
I've tried getting the absolute simplest working implementation of this, and nothing ever shows. Would really appreciate some feedback
View
<od-virtualscroll [vsData]="data" [vsOptions]="options">
<ng-template let-item let-row="row" let-column="column">
<span>Row: {{row}}</span><br>
<span>Column: {{column}}</span>
{{item}}
</ng-template>
</od-virtualscroll>
TS
constructor(private element : ElementRef, public authModel:AuthModel, private services:Services) {
let dateSearch = new DateSearchDescriptor()
dateSearch.zipcode = 11211
this.data = this.services.getDates(dateSearch)
this.options = Observable.of({itemWidth: 202, itemHeight: 202, numAdditionalRows: 1})
}
I am trying to use FocusRowCmd to naviagte to a specific row (in this case i have hard-coded it to row 20)
I couldn't find an implementation of an of the userCmd$ options, the above code snippet does not have the desired affect, it currently only displays the list, but i am expecting it to focus on row 20, i have also tried the same with SetScrollTopCmd and it does not work either. Could you please shed light as to what i am doing wrong? The HTML is below, along with the current output.
and the output
I am expecting something like
i am aware the "names" are the same, that is because my list that i am using is made of 5 entries duplicated around 60 times
thanks
When utilizing the numAdditionalRows parameter, the scrolling experience is dramatically improved as long as the user is scrolling downward.
Unfortunately, it only pads the bottom of the container and not the top. So when scrolling up, the experience is much worse.
It should be updated to pad both, or an additional parameter should be included to specify how many rows you want to render above the container.
There are a couple of angular infinite library. such as ngx-virtual-scroller and ngx-infinite-scroll.
I am actually looking for material cdk virtual scroll. But, it seems that it only support one column based scroll strategy.
I couldn't find a good example using multiple column with CDK virtual.
This library has some advantage comparing to other libraries that I mentioned ?
Looks like this library works nicely with multiple grid columns
I don't see a way to go directly a give item (index) in the list?
In one place where I'm using this, the list starts out only showing items in the top ~60% of the view even though much more space is available and scrollable:
However, this immediately corrects itself when I resize the window once. Also, when displaying elements larger than the ones in the screenshot (using #16), it fills up a little bit more of the available space:
I want to make the entire page infinitely scrollable but also add several titles and hints at the beginning which will scroll away out of sight. look at it like a fixed first row with an undefined height that will not be recycled, just thrown away when out of sight. (like twitter with its "What's happening" line, although there nothing is thrown away or recycled...)
Is it possible?
I install the od-virtualscroll using:
yarn add od-virtualscroll
But when I try to import the module on my own module doesn't find it:
import {VirtualScrollModule} from 'od-virtualscroll';
"Cannot find module od-virtualscroll'
I have my code using angular-cli and angular4
Can anyone help me, certainly I'm doing something wrong
I have tried building the simplest possible demo, lifting the data and template out of scroll.component.ts
from the od-vsstatic
demo:
TEMPLATE
<od-virtualscroll [vsData]="data$" [vsOptions]="options$">
<ng-template let-item let-row="row" let-column="column">
<span>Row: {{row}}</span><br>
<span>Column: {{column}}</span>
{{item}}
</ng-template>
</od-virtualscroll>
OBSERVABLES
data$: Observable<number[]> = range(0, 100000).pipe(
reduce((acc, cur) => { acc.push(cur); return acc; }, []));
options$: Observable<IVirtualScrollOptions> =
of({ itemWidth: 202, itemHeight: 202, numAdditionalRows: 1 });
When I run in the browser I get no rendered output and see this error in the console:
core.js:6162 ERROR TypeError: Cannot read property 'createComponent' of undefined
at od-virtualscroll.js:622
at ScanSubscriber.scanFunc [as accumulator] (od-virtualscroll.js:685)
at ScanSubscriber._tryNext (scan.js:49)
at ScanSubscriber._next (scan.js:42)
at ScanSubscriber.next (Subscriber.js:49)
at MergeMapSubscriber.notifyNext (mergeMap.js:70)
at SimpleInnerSubscriber._next (innerSubscribe.js:10)
at SimpleInnerSubscriber.next (Subscriber.js:49)
at MapSubscriber._next (map.js:35)
at MapSubscriber.next (Subscriber.js:49)
The source line being pointed to is this:
Environment details:
I was unable to get *ngIf statements to work. Anyone else have any success with this?
If I have multiple instances of od-virtualscroll is there a way to determine which instance triggered an observable on ScrollObservableService (scrollWin$, createItem$, etc.)?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.