|
| 1 | +**Warning: this component is still experimental. It may have bugs and the API may change at any |
| 2 | +time** |
| 3 | + |
| 4 | +`<cdk-virtual-scroll-viewport>` is used to display a scrolling list containing a large number of |
| 5 | +items that would have a negative effect on performance if all rendered at once. Instead the virtual |
| 6 | +scroll viewport renders each item as needed when the user scrolls it into view. The |
| 7 | +`<cdk-virtual-scroll-viewport>` works together with the `*cdkVirtualFor` directive which is used to |
| 8 | +render items inside of the viewport. It also requires that a `VirtualScrollStrategy` be provided. |
| 9 | +The easiest way to provide a strategy is with one of the directives `itemSize` or `autosize`. |
| 10 | + |
| 11 | +For some example usages, |
| 12 | +[see the demo app](https://github.com/angular/material2/tree/master/src/demo-app/virtual-scroll). |
| 13 | + |
| 14 | +### Creating items in the viewport |
| 15 | +`*cdkVirtualFor` should be used instead of `*ngFor` to create items in the |
| 16 | +`<cdk-virtual-scroll-viewport>`. `*cdkVirtualFor` supports most of the same features as `*ngFor`. |
| 17 | +The simplest usage just specifies the list of items: |
| 18 | + |
| 19 | +```html |
| 20 | +<cdk-virtual-scroll-viewport itemSize="50"> |
| 21 | + <div *cdkVirtualFor="let item of items">{{item}}</div> |
| 22 | +</cdk-virtual-scroll-viewport> |
| 23 | +``` |
| 24 | + |
| 25 | +`*cdkVirtualFor` makes the following context variables available to the template: |
| 26 | +* `index` - The index of the item in the data source. |
| 27 | +* `count` - The total number of items in the data source. |
| 28 | +* `first` - Whether this is the first item in the data source. |
| 29 | +* `last` - Whether this is the last item in the data source. |
| 30 | +* `even` - Whether the `index` is even. |
| 31 | +* `odd` - Whether the `index` is odd. |
| 32 | + |
| 33 | +All of these apply to the index of the item in the data source, not the index in the rendered |
| 34 | +portion of the data. |
| 35 | + |
| 36 | +```html |
| 37 | +<cdk-virtual-scroll-viewport itemSize="50"> |
| 38 | + <div *cdkVirtualFor="let item of items; |
| 39 | + let index = index; |
| 40 | + let count = count; |
| 41 | + let first = first; |
| 42 | + let last = last; |
| 43 | + let even = even; |
| 44 | + let odd = odd"> |
| 45 | + {{item}} - {{index}} - {{count}} - {{first}} - {{last}} - {{even}} - {{odd}} |
| 46 | + </div> |
| 47 | +</cdk-virtual-scroll-viewport> |
| 48 | +``` |
| 49 | + |
| 50 | +A `trackBy` function can be specified and works the same as the `*ngFor` `trackBy`. The `index` |
| 51 | +passed to the tracking function will be the index in the data source, not the index in the rendered |
| 52 | +portion. |
| 53 | + |
| 54 | +#### View recycling |
| 55 | +In order to improve performance `*cdkVirtualFor` saves the views it creates in a cache when they are |
| 56 | +no longer needed. This way the next time a new view is needed once can be recycled from the cache |
| 57 | +rather than being created from scratch. The size of this cache can be adjusted using the |
| 58 | +`templateCacheSize` input. The cache size defaults to `20` and caching can be disabled by setting it |
| 59 | +to `0`. |
| 60 | + |
| 61 | +```html |
| 62 | +<cdk-virtual-scroll-viewport itemSize="50"> |
| 63 | + <div *cdkVirtualFor="let item of items; templateCacheSize: 0">{{item}}</div> |
| 64 | +</cdk-virtual-scroll-viewport> |
| 65 | +``` |
| 66 | + |
| 67 | +#### Specifying items with an Observable or DataSource |
| 68 | +`*cdkVirtualFor` is set up to accept data from an `Array`, `Observable`, or `DataSource`. The |
| 69 | +`DataSource` for the virtual scroll is the same one used by the table and tree components. A |
| 70 | +`DataSource` is simply an abstract class that has two methods: `connect` and `disconnect`. The |
| 71 | +`connect` method will be called by the virtual scroll viewport to receive a stream that emits the |
| 72 | +data array that should be rendered. The viewport will call `disconnect` when the viewport is |
| 73 | +destroyed, which may be the right time to clean up any subscriptions that were registered during the |
| 74 | +connect process. |
| 75 | + |
| 76 | +### Scrolling over fixed size items |
| 77 | +If you're scrolling over a list of items that are all the same fixed size, you can use the |
| 78 | +`FixedSizeVirtualScrollStrategy`. This can be easily added to your viewport using the `itemSize` |
| 79 | +directive. |
| 80 | + |
| 81 | +```html |
| 82 | +<cdk-virtual-scroll-viewport itemSize="50"> |
| 83 | + ... |
| 84 | +</cdk-virtual-scroll-viewport> |
| 85 | +``` |
| 86 | + |
| 87 | +The fixed size strategy also supports setting the buffer size, i.e. the number of items rendered |
| 88 | +beyond the edge of the viewport. This can be adjusted by setting the `bufferSize` input. If not |
| 89 | +specified, the `bufferSize` defaults to `5`. |
| 90 | + |
| 91 | +```html |
| 92 | +<cdk-virtual-scroll-viewport itemSize="50" bufferSize="1"> |
| 93 | + ... |
| 94 | +</cdk-virtual-scroll-viewport> |
| 95 | +``` |
| 96 | + |
| 97 | +**Note: The fixed size strategy will likely be changed to allow specifying a separate |
| 98 | +`minBufferPx` and `addBufferPx` like the autosize strategy** |
| 99 | + |
| 100 | +### Scrolling over items with different sizes |
| 101 | +If you're scrolling over a list of items with different sizes, you can use the |
| 102 | +`AutoSizeVirtualScrollStrategy`. This can be added to your viewport by using the `autosize` |
| 103 | +directive. |
| 104 | + |
| 105 | +```html |
| 106 | +<cdk-virtual-scroll-viewport autosize> |
| 107 | + ... |
| 108 | +</cdk-virtual-scroll-viewport> |
| 109 | +``` |
| 110 | + |
| 111 | +The `autosize` strategy allows the buffer to be configured through two inputs `minBufferPx` and |
| 112 | +`addBufferPx`. The `minBufferPx` is the minimum amount of buffer (in pixels) that the viewport |
| 113 | +should try to maintain on either side of the viewport. The `addBufferPx` is the amount of buffer |
| 114 | +(in pixels) that the viewport should try to render out when it detects that the buffer has dropped |
| 115 | +below the `minBufferPx`. It's helpful for this to be a little larger than the `minBufferPx` as it |
| 116 | +allows the viewport to render out new buffer items in batches rather than constantly needing to |
| 117 | +render new ones. By default the `minBufferPx` is `100` and the default `addBufferPx` is `200`. |
| 118 | + |
| 119 | +```html |
| 120 | +<cdk-virtual-scroll-viewport autosize minBufferPx="50" addBufferPx="100"> |
| 121 | + ... |
| 122 | +</cdk-virtual-scroll-viewport> |
| 123 | +``` |
| 124 | + |
| 125 | +Because the auto size strategy needs to measure the size of the elements, its performance may not |
| 126 | +be as good as the fixed size strategy. |
| 127 | + |
| 128 | +### Setting the viewport orientation |
| 129 | +The orientation of the viewport can be adjusted by using the `orientation` input. It defaults to |
| 130 | +`vertical` which virtualizes scrolling along the y-axis. It can be set to `horizontal` to virtualize |
| 131 | +scrolling along the x-axis. If you use this option you need to make sure that the content is |
| 132 | +actually laid out so that it extends along the x-axis. To do this you may want to target CSS at |
| 133 | +`.cdk-virtual-scroll-content-wrapper` which is the wrapper element that contains the rendered |
| 134 | +content. |
| 135 | + |
| 136 | +```html |
| 137 | +<cdk-virtual-scroll-viewport autosize orientation="horizontal"> |
| 138 | + ... |
| 139 | +</cdk-virtual-scroll-viewport> |
| 140 | +``` |
0 commit comments