GithubHelp home page GithubHelp logo

dinony / od-virtualscroll Goto Github PK

View Code? Open in Web Editor NEW
134.0 134.0 12.0 126 KB

🚀 Observable-based virtual scroll implementation in Angular

Home Page: https://dinony.github.io/od-vsstatic/

License: MIT License

JavaScript 6.40% TypeScript 93.60%
angular angular-component aot-compilation infinite-scroll observable od-virtualscroll reactive-programming rxjs tileview tiling virtual-scroll virtual-scroller

od-virtualscroll's People

Contributors

dinony avatar zy-serguei avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

od-virtualscroll's Issues

horizontal scroll

Hi Dinony,
Do you plan horizontal scrolling?
Thanks for your cool library!

How to remove an item example?

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);
      }));

[bug report] AOT support broken

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.

[feature request] Iterable support

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.

How can I integrate a search/filter functionality?

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?

Prefered way to force redraw of rows/items.

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);
      }));

Initial scroll position

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).

Async data

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?

[feature request] Variable item height

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.

responsive flexLayout example

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....

[bug report] Resizing broken

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%; }.

ios/android No Items are rendering.

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.

Incorrect positioning

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.

screen shot 2017-12-05 at 7 50 05 pm

Scrollbar is out of sync for larger number of items in IE11

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.

https://stackblitz.com/edit/angular-pdtfw7

Getting errors when using fxFlex in template

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)

Cannot get anything to display

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})
  }

FocusRowIndex

I am trying to use FocusRowCmd to naviagte to a specific row (in this case i have hard-coded it to row 20)

scrollcomponenet

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.

html

and the output

scroll

I am expecting something like

row20

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

numAdditionalRows only pads the bottom of the container

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.

What is advantage of this library?

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

Incorrect height

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:

screen shot 2017-12-05 at 8 02 29 pm

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:

screen shot 2017-12-05 at 10 07 51 pm

Additional content in virtual scroll

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?

Problem to import module

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

Component throws console error in new installation

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:

const newRow = this._viewContainer.createComponent(this._rowFactory)

Environment details:

  • Browser: Chrome
  • OS: macOS Big Sur
  • Angular: 11

ngIf not working

I was unable to get *ngIf statements to work. Anyone else have any success with this?

Multiple instances

If I have multiple instances of od-virtualscroll is there a way to determine which instance triggered an observable on ScrollObservableService (scrollWin$, createItem$, etc.)?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.