Closed jelbourn closed 6 years ago
Would be good to implement dynamic height (https://github.com/angular/material/issues/4314)
Does someone know a repo do this virtual scroll instead of ngFor ? Today we have a very large set of data, it's primordial to begin/HAVE this feature instead of something like "tooltip" or so ! @jelbourn Displaying big data is important today please begin with something hard instead of "tooltip"
ps: https://developers.google.com/web/updates/2016/07/infinite-scroller
@istiti Polymer has <iron-list>
Here and Demos Here
Please recognize that you are asking about a feature that most projects don't need/use and is a technical challenge to put into a library in a fully formed, universal way... You could probably write your own version, but it might not be what I would need...
Tooltip is a super easy use case for portals and overlay's which are core to everything from menu's to dialogs so is rather simple to release and common enough that most use cases fit.
The link you gave has a link to his source code and it's only 400ish lines. I bet you could make a ng2 version and contributing it back to the community for free would be awesome!
@DennisSmolek "Infinite scrollers pop up all over the internet. Google Music’s artist list is one, Facebook’s timeline is one and Twitter’s live feed is one as well" IMHO infinite scroll is technik people need to have to discharge their DOM! Still more today we have big data.
Impossible to get iron list working (very comlpicate) if you have an github repo doing virtual Dom, you're welcome
@istiti Have you tried this https://github.com/vaadin/angular2-polymer
https://vaadin.com/blog/-/blogs/using-polymer-components-in-angular-2
yes but this add more complexities to my app ... really a bad choice but I find angular2-data-table which do work very awesome thanks
ETA?
I've ported the old one and wonder if I there's some form of spec available so I can align my implementation with it. The mdVirtualRepeat is almost (as in line-to-line) the same, but structural repeater had to be made by scratch based on ngFor and mdVirtualRepeat.
@Klaster1 , any chance you could fork material2 and add your work to the library? If there was at least an initial PR we could get some momentum going behind this.
ngx-datatable has an implementation of virtual scroll.
I wonder if that couldn't be easily brought in?
@jelbourn I've made a naive implementation of a templatizable-virtual-repeat that work great for basic use-cases. However, the item repeated must have a fixed height. For now the virtual-repeat only supports: itemNumber * itemHeight / maxHeight of HTMLElement of the browser which is 33554400px in Chrome. So the number of items to be virtualized is still limited and relative to their heights.
If this sounds good to you, I can make a PR with the initial version and if the components pleases most I can work on the maxHeight issue.
Let me know if you're interested.
@thibaultsavary we want to explore solutions for non fix-sized items in material2.
@jelbourn is that the sort of thing that can be implemented in a version bump down the road? Variable height is a tricky issue to solve with virtual repeaters, and I'm not sure insisting upon its inclusion is a realistic goal.
If we could at least get feature parity with Angular Material 1.0, it would be a massive help; Our company is pretty dependent on md-virtual-repeat
, and its lack of support in Angular Material 2.0 is a bit of a blocker for us to upgrade to Angular ^2.
To be sure, flexible height would be a great feature, I'm just not sure it's as much of a requirement as having virtual repeat in the first place.
@jelbourn I fully agree with @bryanrideshark for virtual scroll to be exact in height is not top priority. Exact position affects scrollbar position on the right, but normally it is only a visual effect.
@bryanrideshark & @laserus I don't agree with you guys... if the team implements the v1 (from material 1), a better version will probably never be explored! The team's time is limited and they should focus on innovation rather than existing technologies
+1 for innovation
ps:wait this feature since 5 months
+1 for the flexible height.
@natcohen all of what will / will not happen is speculation unless we're actually decision makers in the matter, IE, core members of the team.
As this is a blocking issue for other things (autocomplete, md-select), would someone on the team be able to provide some sort of feedback as to where this issue stands?
+1 for the flexible height
+1 need this badly!
I have an implementation for virtual grids: https://github.com/Hacklone/angular2-cool-infinite-grid Maybe grids could be part of virtual scrolling too :)
there aren't virtual scroll component In milestones. Are you planning to implement it?
https://github.com/dinony/od-virtualscroll is working great in my project, and so far is the only one I've tested that I could get working (the others might not have liked @angular/flex-layout, not sure).
It doesn't yet support dynamic item height, so for now we're just using it in a feature branch, but otherwise seems like a really good implementation.
@buu700 do you know if it supports flexLayout?
@mackelito, yep, they seem to be working well together; I just had to include a small CSS workaround. This is what my implementation looks like:
od-virtualscroll, od-virtualrow {
width: 100%;
}
...
<div fxFlexFill fxLayout='column'>
<od-virtualscroll fxFlexFill>
<ng-template let-item let-row='row'>
...
</ng-template>
</od-virtualscroll>
</div>
Also potentially helpful (not material/flex-layout-specific): https://github.com/dinony/od-virtualscroll/issues/2#issuecomment-301191176
+1 for the flexible height.
What do you mean by flexible height, Do you expect the repeater to calculate the height by itself and assume that all items has the same height or you wish for every item to have it's own different height? I am asking because I already implemented this component and the former wish is crazy. The first is simple though, before creating the components loop, just build the first component and then calculate it's height...
@MadUser customizable height calculation function might be good enough. Default implementation will measure first item or use number value from binding/config object. If you can calculate each item dimensions reliably, variable size will work. For example, if each virtual list item is another list of items of predefined size, just multiply item height and items amount (in simpliest case).
I'm currently using this one: https://github.com/rintoj/angular2-virtual-scroll Works great
Any updates on this?
@elineopsommer they have updated the feature status in the info page to "planned Q3 2017"... Q3 has just started so just be patient :)
@elineopsommer where is the info page?
Huh after reading through the comments i am surprised how complicated you guys want to make it. Isn't enough just to set the scroll distance for triggering an event to load more data. I see no point of being unable to be innovative with this. A working version that works simply should be enough and covers the most use cases. You can then be innovative and add more features?
Some people disagree, @azarus. Why would you be on a team that is commited to create something with the best design principles and will just ignore this fact to create something that is already there? If your use case is simple, just work with some third-party library (or make a component) that fulfill your needs. The team cannot just start with something simple now, before designing with all cenarios in mind, as this may lead to a bad/wrong spec to other more complex cenarios.
Following your example, there is already other projects that can do what your want. For instance: https://github.com/rintoj/angular2-virtual-scroll. This is a nice implementation, but doesn't follow Angular Material principles. I think that's why the team is taking "so long" to implement the entire library with the best UI components in mind: design everything really well.
In a project that I am participating now, an use case for the virtual repeat component is a grid of images, that I load records from a service. My intent with this is to show it to the user like I would do using a RecyclerView (the Android component). And, in my opinion, this is where virtual scroll could be taken: a "mimic" of a RecyclerView that allows us to display an interesting UI without loading all the records upfront, but with the items "size" already defined (as we can run a simple count in database to check this quickly). This will help us to deliver better UI/UX to the user: a nice component to interact with and with great performance too.
The scrolling is already implemented in material but there are no such events yet as far as i see :/
I think we aren't talking about the same thing here, @azarus. This issue is about tracking the Virtual Scroll/Repeat implementation for Material UI of Angular 2. It's not implemented yet. Not even designed.
The only news from it is an update (a couple of days ago) regarding the plan to start designing this component, that was postponed to Q4 this year.
Anyway... I have a lot of expectations about this component and hope to see it covering complex use cases too, not only what we already can do with any UI library today. This is what I think the team behind Material wants too and the work to polish everything is something big, but the results tend to be very promising.
One year later...
Just wait for them as they said they gona reinvent the wheel in an innovative way. :) such a joke.
@azarus as one that is inspired by the Material team and their work I take comments like this as hurtful to this community. I understand you're frustrated with the lack of progress on this particular issue, but the team has been working their ass off on bringing core functionality with i18n, a11y, and the cdk. Your comments have added zero benefit to this thread.
I ask that you please resign from commenting.
I found brilliant solution from slickgrid. This is basically handles unlimited records of any size (I don't think variable height can be handled in this case) and I have implemented the solution preview, comments added. This solution performance is too good compare to any solutions exist today. May be material team can consider to adopt it?
@cgatian then stop mentioning me in your fan comments? I do like material but this is slightly anoing how no progress is shown regarding this feature. If a complaint is hurtful because the team puts resources into reinvention rather than delivering it then it better be damn good?
@azarus +1
It's like google is very cool and have no profit to make all developer use angular or other. All is open source open source open source open source lol
This thread need tobe blocked
Yep, need to be blocked until it will be done or in progress.
Also take a look at https://github.com/tbranyen/hyperlist , non angular pure js version.
@jelbourn I know this isn't planned for post beta but was wondering if there was any API proposals floating around for this? I've been looking at a few different ways this could be implemented but wanted to check to see if what I've come up matches anything that the team might already have in mind.
Hello, Here is my own implementation of the virtual-scroll, inspired from one of AngularJs but coded by me, it does not support dynamic height of items but has really great performances (works perfectly well on CPU 6x slowdown with a fade-in animation for items).
Usage:
<optimized-list [items]="products" [itemHeight]="73" [offset]="2" (update)="optimizedList = $event">
<!-- It supports animations: -->
<div [@reveal] *ngFor="let product of optimizedList">
{{product.name}}
</div>
</optimized-list>
nb: "offset" represents the number of element preloaded (item rendered but not in the view) to prevent "pop-in" effect. This parameter is optional and default to 0, it's completely OK to keep it at default but you should add a fade-in animation. A really good compromise is to set it to 2 with a fade-in animation. It performs really well on low-end devices.
component.html A "fake-scroller" is an empty box in which the user can scroll, it has the total height of the list, the content is not in this "fake-scroller" but on top and will be translated using the css translateY function.
<div id="fake-scroller" [style.height]="scrollHeight + 'px'"></div>
<div id="content-wrapper" [style.transform]="'translateY(' + translateY + 'px)'">
<ng-content></ng-content>
</div>
component.ts
import { Component, OnInit, OnChanges, SimpleChanges, Input, Output, EventEmitter, Renderer, ElementRef, HostListener } from '@angular/core';
@Component({
selector: 'optimized-list',
templateUrl: './optimized-list.component.html',
styleUrls: ['./optimized-list.component.css']
})
export class OptimizedListComponent implements OnChanges {
/*
My own implementation of a virtual-scroll component
~Robin
*/
@Input() items: any[]; //the items to display
@Input() itemHeight: number = 20;
@Input() offset: number = 0;
@Output() update: EventEmitter<any[]> = new EventEmitter<any[]>();
@HostListener('scroll') onScroll = function () {
this.refresh();
}
public scrollHeight: number;
public translateY: number;
private visibleItems: any[] = [];
constructor(
private renderer: Renderer,
private elementRef: ElementRef,
) { }
ngOnChanges(changes: SimpleChanges) {
for (let propName in changes) {
if (propName == 'items') {
this.scrollHeight = this.items.length * this.itemHeight + 88; // + 88 // offset bottom
//This offset is not necessary but I think the list should support both top and bottom offsets via parameters
this.refresh();
}
}
}
private refresh() {
let height: number = this.elementRef.nativeElement.clientHeight;
let scrollTop: number = this.elementRef.nativeElement.scrollTop;
let visual_start: number = Math.floor(scrollTop / this.itemHeight);
let offset_start: number = Math.max(Math.floor(scrollTop / this.itemHeight) - this.offset, 0);
let offset_end: number = Math.min(Math.ceil((height + scrollTop) / this.itemHeight) + this.offset, this.items.length);
this.translateY = Math.min(scrollTop - (visual_start - offset_start) * this.itemHeight - (scrollTop % this.itemHeight), this.items.length * this.itemHeight);
this.visibleItems = this.items.slice(offset_start, offset_end);
this.update.next(this.visibleItems);
}
}
component.css Nothing special about the css:
:host{
display: block;
position: relative;
overflow: hidden;
overflow-y: scroll;
will-change: transform;
}
#fake-scroller{
height: 100%;
}
#content-wrapper{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
@jelbourn, any news on the progress of this? It's Q4 now isn't it? 😃
@mmalerba is working on it- it's a large project, so it was started in Q4 and is planned to wrap up in 2018.
@jelbourn will it support dynamic height of elements? It is a really important feature in my opinion.
Yes, that is something we aim to support (and one of the reasons it's a larger undertaking)
Similar to the
md-virtual-repeat
in Angular Material 1.