docs(virtual-scroll): add live examples (#13327)

This commit is contained in:
mmalerba
2018-09-27 13:51:32 -07:00
committed by Jeremy Elbourn
parent fd3eb6acc5
commit 5321ab3cc4
22 changed files with 311 additions and 45 deletions
+8 -45
View File
@@ -27,11 +27,7 @@ rest.
same API as [`*ngFor`](https://angular.io/api/common/NgForOf). The simplest usage just specifies the
list of items:
```html
<cdk-virtual-scroll-viewport itemSize="50">
<div *cdkVirtualFor="let item of items">{{item}}</div>
</cdk-virtual-scroll-viewport>
```
<!-- example(cdk-virtual-scroll-overview) -->
`*cdkVirtualFor` makes the following context variables available to the template:
@@ -47,15 +43,7 @@ list of items:
All of these apply to the index of the item in the data source, not the index in the rendered
portion of the data.
```html
<cdk-virtual-scroll-viewport itemSize="50">
<div *cdkVirtualFor="let item of items;
let index = index;
let count = count">
{{item}} ({{index}} of {{count}})
</div>
</cdk-virtual-scroll-viewport>
```
<!-- example(cdk-virtual-scroll-context) -->
A `trackBy` function can be specified and works the same as the `*ngFor` `trackBy`. The `index`
passed to the tracking function will be the index in the data source, not the index in the rendered
@@ -68,11 +56,7 @@ is reused instead. The size of the view cache can be adjusted via the `templateC
property; setting this size to `0` disables caching. If your templates are expensive in terms of
memory you may wish to reduce this number to avoid spending too much memory on the template cache.
```html
<cdk-virtual-scroll-viewport itemSize="50">
<div *cdkVirtualFor="let item of items; templateCacheSize: 0">{{item}}</div>
</cdk-virtual-scroll-viewport>
```
<!-- example(cdk-virtual-scroll-template-cache) -->
##### Specifying data
`*cdkVirtualFor` accepts data from an `Array`, `Observable<Array>`, or `DataSource`. The
@@ -83,17 +67,13 @@ data array that should be rendered. The viewport will call `disconnect` when the
destroyed, which may be the right time to clean up any subscriptions that were registered during the
connect process.
<!-- example(cdk-virtual-scroll-data-source) -->
#### Scrolling over fixed size items
When all items are the same fixed size, you can use the `FixedSizeVirtualScrollStrategy`. This can
be easily added to your viewport using the `itemSize` directive. The advantage of this constraint is
that it allows for better performance, since items do not need to be measured as they are rendered.
```html
<cdk-virtual-scroll-viewport itemSize="50">
...
</cdk-virtual-scroll-viewport>
```
The fixed size strategy also supports setting a couple of buffer parameters that determine how much
extra content is rendered beyond what is visible in the viewport. The first of these parameters is
`minBufferPx`. The `minBufferPx` is the minimum amount of content buffer (in pixels) that the
@@ -108,11 +88,7 @@ remaining. Since this is below `minBufferPx` the viewport must render more buffe
least enough buffer to get back to `maxBufferPx`. In this case, it renders 4 items (an additional
`200px`) to bring the total buffer size to `290px`, back above `maxBufferPx`.
```html
<cdk-virtual-scroll-viewport itemSize="50" minBufferPx="100" maxBufferPx="250">
...
</cdk-virtual-scroll-viewport>
```
<!-- example(cdk-virtual-scroll-fixed-buffer) -->
Other virtual scrolling strategies can be implemented by extending `VirtualScrollStrategy`. An
autosize strategy that works on elements of differing sizes is currently being developed in
@@ -125,11 +101,7 @@ out horizontally via CSS. To do this you may want to target CSS at
`.cdk-virtual-scroll-content-wrapper` which is the wrapper element that contains the rendered
content.
```html
<cdk-virtual-scroll-viewport itemSize="50" orientation="horizontal">
...
</cdk-virtual-scroll-viewport>
```
<!-- example(cdk-virtual-scroll-horizontal) -->
### Elements with parent tag requirements
Some HTML elements such as `<tr>` and `<li>` have limitations on the kinds of parent elements they
@@ -138,13 +110,4 @@ their proper parent, and then wrap the whole thing in a `cdk-virtual-scroll-view
that the parent does not introduce additional space (e.g. via `margin` or `padding`) as it will
interfere with the scrolling.
```html
<cdk-virtual-scroll-viewport itemSize="50">
<table>
<tr *cdkVirtualFor="let row of rows">
<td>{{row.first}}</td>
<td>{{row.second}}</td>
</tr>
</table>
</cdk-virtual-scroll-viewport>
```
<!-- example(cdk-virtual-scroll-dl) -->
@@ -0,0 +1,13 @@
.example-viewport {
height: 200px;
width: 200px;
border: 1px solid black;
}
.example-item-detail {
height: 18px;
}
.example-alternate {
background: rgba(127, 127, 127, 0.3);
}
@@ -0,0 +1,17 @@
<cdk-virtual-scroll-viewport [itemSize]="18 * 7" class="example-viewport">
<div *cdkVirtualFor="let item of items;
let index = index;
let count = count;
let first = first;
let last = last;
let even = even;
let odd = odd;" [class.example-alternate]="odd">
<div class="example-item-detail">Item: {{item}}</div>
<div class="example-item-detail">Index: {{index}}</div>
<div class="example-item-detail">Count: {{count}}</div>
<div class="example-item-detail">First: {{first ? 'Yes' : 'No'}}</div>
<div class="example-item-detail">Last: {{last ? 'Yes' : 'No'}}</div>
<div class="example-item-detail">Event: {{even ? 'Yes' : 'No'}}</div>
<div class="example-item-detail">Odd: {{odd ? 'Yes' : 'No'}}</div>
</div>
</cdk-virtual-scroll-viewport>
@@ -0,0 +1,12 @@
import {ChangeDetectionStrategy, Component} from '@angular/core';
/** @title Virtual scroll context variables */
@Component({
selector: 'cdk-virtual-scroll-context-example',
styleUrls: ['cdk-virtual-scroll-context-example.css'],
templateUrl: 'cdk-virtual-scroll-context-example.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class CdkVirtualScrollContextExample {
items = Array.from({length: 100000}).map((_, i) => `Item #${i}`);
}
@@ -0,0 +1,9 @@
.example-viewport {
height: 200px;
width: 200px;
border: 1px solid black;
}
.example-item {
height: 50px;
}
@@ -0,0 +1,3 @@
<cdk-virtual-scroll-viewport itemSize="50" class="example-viewport">
<div *cdkVirtualFor="let item of ds" class="example-item">{{item || 'Loading...'}}</div>
</cdk-virtual-scroll-viewport>
@@ -0,0 +1,57 @@
import {CollectionViewer, DataSource} from '@angular/cdk/collections';
import {ChangeDetectionStrategy, Component} from '@angular/core';
import {BehaviorSubject, Observable, Subscription} from 'rxjs';
/** @title Virtual scroll with a custom data source */
@Component({
selector: 'cdk-virtual-scroll-data-source-example',
styleUrls: ['cdk-virtual-scroll-data-source-example.css'],
templateUrl: 'cdk-virtual-scroll-data-source-example.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class CdkVirtualScrollDataSourceExample {
ds = new MyDataSource();
}
export class MyDataSource extends DataSource<string | undefined> {
private length = 100000;
private pageSize = 100;
private cachedData = Array.from<string>({length: this.length});
private fetchedPages = new Set<number>();
private dataStream = new BehaviorSubject<(string | undefined)[]>(this.cachedData);
private subscription = new Subscription();
connect(collectionViewer: CollectionViewer): Observable<(string | undefined)[]> {
this.subscription.add(collectionViewer.viewChange.subscribe(range => {
const startPage = this.getPageForIndex(range.start);
const endPage = this.getPageForIndex(range.end - 1);
for (let i = startPage; i <= endPage; i++) {
this.fetchPage(i);
}
}));
return this.dataStream;
}
disconnect(): void {
this.subscription.unsubscribe();
}
private getPageForIndex(index: number): number {
return Math.floor(index / this.pageSize);
}
private fetchPage(page: number) {
if (this.fetchedPages.has(page)) {
return;
}
this.fetchedPages.add(page);
// Use `setTimeout` to simulate fetching data from server.
setTimeout(() => {
this.cachedData.splice(page * this.pageSize, this.pageSize,
...Array.from({length: this.pageSize})
.map((_, i) => `Item #${page * this.pageSize + i}`));
this.dataStream.next(this.cachedData);
}, Math.random() * 1000 + 200);
}
}
@@ -0,0 +1,14 @@
.example-viewport {
height: 200px;
width: 200px;
border: 1px solid black;
}
.example-dt {
height: 30px;
font-weight: bold;
}
.example-dd {
height: 30px;
}
@@ -0,0 +1,8 @@
<cdk-virtual-scroll-viewport class="example-viewport" itemSize="60">
<dl class="example-dl">
<ng-container *cdkVirtualFor="let state of states">
<dt class="example-dt">{{state.name}}</dt>
<dd class="example-dd">{{state.capital}}</dd>
</ng-container>
</dl>
</cdk-virtual-scroll-viewport>
@@ -0,0 +1,63 @@
import {ChangeDetectionStrategy, Component} from '@angular/core';
/** @title Virtual scrolling `<dl>` */
@Component({
selector: 'cdk-virtual-scroll-dl-example',
styleUrls: ['cdk-virtual-scroll-dl-example.css'],
templateUrl: 'cdk-virtual-scroll-dl-example.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class CdkVirtualScrollDlExample {
states = [
{name: 'Alabama', capital: 'Montgomery'},
{name: 'Alaska', capital: 'Juneau'},
{name: 'Arizona', capital: 'Phoenix'},
{name: 'Arkansas', capital: 'Little Rock'},
{name: 'California', capital: 'Sacramento'},
{name: 'Colorado', capital: 'Denver'},
{name: 'Connecticut', capital: 'Hartford'},
{name: 'Delaware', capital: 'Dover'},
{name: 'Florida', capital: 'Tallahassee'},
{name: 'Georgia', capital: 'Atlanta'},
{name: 'Hawaii', capital: 'Honolulu'},
{name: 'Idaho', capital: 'Boise'},
{name: 'Illinois', capital: 'Springfield'},
{name: 'Indiana', capital: 'Indianapolis'},
{name: 'Iowa', capital: 'Des Moines'},
{name: 'Kansas', capital: 'Topeka'},
{name: 'Kentucky', capital: 'Frankfort'},
{name: 'Louisiana', capital: 'Baton Rouge'},
{name: 'Maine', capital: 'Augusta'},
{name: 'Maryland', capital: 'Annapolis'},
{name: 'Massachusetts', capital: 'Boston'},
{name: 'Michigan', capital: 'Lansing'},
{name: 'Minnesota', capital: 'St. Paul'},
{name: 'Mississippi', capital: 'Jackson'},
{name: 'Missouri', capital: 'Jefferson City'},
{name: 'Montana', capital: 'Helena'},
{name: 'Nebraska', capital: 'Lincoln'},
{name: 'Nevada', capital: 'Carson City'},
{name: 'New Hampshire', capital: 'Concord'},
{name: 'New Jersey', capital: 'Trenton'},
{name: 'New Mexico', capital: 'Santa Fe'},
{name: 'New York', capital: 'Albany'},
{name: 'North Carolina', capital: 'Raleigh'},
{name: 'North Dakota', capital: 'Bismarck'},
{name: 'Ohio', capital: 'Columbus'},
{name: 'Oklahoma', capital: 'Oklahoma City'},
{name: 'Oregon', capital: 'Salem'},
{name: 'Pennsylvania', capital: 'Harrisburg'},
{name: 'Rhode Island', capital: 'Providence'},
{name: 'South Carolina', capital: 'Columbia'},
{name: 'South Dakota', capital: 'Pierre'},
{name: 'Tennessee', capital: 'Nashville'},
{name: 'Texas', capital: 'Austin'},
{name: 'Utah', capital: 'Salt Lake City'},
{name: 'Vermont', capital: 'Montpelier'},
{name: 'Virginia', capital: 'Richmond'},
{name: 'Washington', capital: 'Olympia'},
{name: 'West Virginia', capital: 'Charleston'},
{name: 'Wisconsin', capital: 'Madison'},
{name: 'Wyoming', capital: 'Cheyenne'},
];
}
@@ -0,0 +1,9 @@
.example-viewport {
height: 200px;
width: 200px;
border: 1px solid black;
}
.example-item {
height: 50px;
}
@@ -0,0 +1,4 @@
<cdk-virtual-scroll-viewport itemSize="50" minBufferPx="200" maxBufferPx="400"
class="example-viewport">
<div *cdkVirtualFor="let item of items" class="example-item">{{item}}</div>
</cdk-virtual-scroll-viewport>
@@ -0,0 +1,12 @@
import {ChangeDetectionStrategy, Component} from '@angular/core';
/** @title Fixed size virtual scroll with custom buffer parameters */
@Component({
selector: 'cdk-virtual-scroll-fixed-buffer-example',
styleUrls: ['cdk-virtual-scroll-fixed-buffer-example.css'],
templateUrl: 'cdk-virtual-scroll-fixed-buffer-example.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class CdkVirtualScrollFixedBufferExample {
items = Array.from({length: 100000}).map((_, i) => `Item #${i}`);
}
@@ -0,0 +1,16 @@
.cdk-virtual-scroll-data-source-example .example-viewport {
height: 200px;
width: 200px;
border: 1px solid black;
}
.cdk-virtual-scroll-data-source-example .example-viewport .cdk-virtual-scroll-content-wrapper {
display: flex;
flex-direction: row;
}
.cdk-virtual-scroll-data-source-example .example-item {
width: 50px;
height: 100%;
writing-mode: vertical-lr;
}
@@ -0,0 +1,5 @@
<div class="cdk-virtual-scroll-data-source-example">
<cdk-virtual-scroll-viewport orientation="horizontal" itemSize="50" class="example-viewport">
<div *cdkVirtualFor="let item of items" class="example-item">{{item}}</div>
</cdk-virtual-scroll-viewport>
</div>
@@ -0,0 +1,13 @@
import {ChangeDetectionStrategy, Component, ViewEncapsulation} from '@angular/core';
/** @title Horizontal virtual scroll */
@Component({
selector: 'cdk-virtual-scroll-horizontal-example',
styleUrls: ['cdk-virtual-scroll-horizontal-example.css'],
templateUrl: 'cdk-virtual-scroll-horizontal-example.html',
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class CdkVirtualScrollHorizontalExample {
items = Array.from({length: 100000}).map((_, i) => `Item #${i}`);
}
@@ -0,0 +1,9 @@
.example-viewport {
height: 200px;
width: 200px;
border: 1px solid black;
}
.example-item {
height: 50px;
}
@@ -0,0 +1,3 @@
<cdk-virtual-scroll-viewport itemSize="50" class="example-viewport">
<div *cdkVirtualFor="let item of items" class="example-item">{{item}}</div>
</cdk-virtual-scroll-viewport>
@@ -0,0 +1,12 @@
import {ChangeDetectionStrategy, Component} from '@angular/core';
/** @title Basic virtual scroll */
@Component({
selector: 'cdk-virtual-scroll-overview-example',
styleUrls: ['cdk-virtual-scroll-overview-example.css'],
templateUrl: 'cdk-virtual-scroll-overview-example.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class CdkVirtualScrollOverviewExample {
items = Array.from({length: 100000}).map((_, i) => `Item #${i}`);
}
@@ -0,0 +1,9 @@
.example-viewport {
height: 200px;
width: 200px;
border: 1px solid black;
}
.example-item {
height: 50px;
}
@@ -0,0 +1,3 @@
<cdk-virtual-scroll-viewport itemSize="50" class="example-viewport">
<div *cdkVirtualFor="let item of items; templateCacheSize: 0" class="example-item">{{item}}</div>
</cdk-virtual-scroll-viewport>
@@ -0,0 +1,12 @@
import {ChangeDetectionStrategy, Component} from '@angular/core';
/** @title Virtual scroll with no template caching */
@Component({
selector: 'cdk-virtual-scroll-template-cache-example',
styleUrls: ['cdk-virtual-scroll-template-cache-example.css'],
templateUrl: 'cdk-virtual-scroll-template-cache-example.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class CdkVirtualScrollTemplateCacheExample {
items = Array.from({length: 100000}).map((_, i) => `Item #${i}`);
}