Skip to content
A plugin that provides a virtualized repeater and other virtualization services.
Branch: master
Clone or download
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.circleci chore(all): fix ci, add demo app, fix readme Jan 20, 2019
.vscode chore(dev): add tsdk, auto lint Apr 4, 2019
build chore(build): adjust deps, jspm, add changelog scripts Jan 12, 2019
dist chore(all): prepare release 1.0.0-beta.7 May 6, 2019
doc chore(all): prepare release 1.0.0-beta.7 May 6, 2019
sample chore(all): clean up, fix scrolling tests Apr 8, 2019
src chore(build): fix virtual repeat impl interface May 3, 2019
test chore(all): clean up, fix scrolling tests Apr 8, 2019
.editorconfig chore(all): setup repo Jun 27, 2015
.gitignore chore(build): update deps, tsconfig target Mar 16, 2019
.npmignore chore(all): clarify interfaces, add comments for properties Feb 20, 2019
CONTRIBUTING.md chore(all): setup repo Jun 27, 2015
ISSUE_TEMPLATE.md chore(issue_template): fix company and email Sep 22, 2016
LICENSE chore(LICENSE): update dates Jan 1, 2018
README.md refactore(all): more cleanup Apr 6, 2019
bower.json chore(all): prepare release 1.0.0-beta.7 May 6, 2019
karma.conf.js fix(repeat): correctly handle mutation Mar 12, 2019
package-lock.json chore(build): update deps, tsconfig target Mar 16, 2019
package.json chore(all): prepare release 1.0.0-beta.7 May 6, 2019
rollup.config.js build(all): adjust umd build, add umd-es2015 for unpkg Mar 23, 2019
tsconfig.json chore(build): update deps, tsconfig target Mar 16, 2019
tslint.json chore(lint): remove no-bitwise lint rule Mar 19, 2019
typings.json chore(all): prepare release 0.5.1 Jun 17, 2016

README.md

aurelia-ui-virtualization

npm Version Join the chat at https://gitter.im/aurelia/discuss CircleCI

This library is part of the Aurelia platform and contains a plugin that provides a virtualized repeater and other virtualization services. This plugin enables "virtualization" of list through a new virtual-repeat.for. When used, the list "virtually" as tens or hundreds of thousands of rows, but the DOM only actually has rows for what is visible. It could be only tens of items. This allows rendering of massive lists of data with amazing performance. It works like repeat.for, it just creates a scrolling area and manages the list using UI virtualization techniques.

To keep up to date on Aurelia, please visit and subscribe to the official blog and our email list. We also invite you to follow us on twitter. If you have questions look around our Discourse forums, chat in our community on Gitter or use stack overflow. Documentation can be found in our developer hub. If you would like to have deeper insight into our development process, please install the ZenHub Chrome or Firefox Extension and visit any of our repository's boards.

Installation

Install via JSPM

jspm install aurelia-ui-virtualization

Load the plugin

export function configure(aurelia) {
  aurelia.use
    .standardConfiguration()
    .developmentLogging()
    .plugin('aurelia-ui-virtualization'); // Add this line to load the plugin

  aurelia.start().then(a => a.setRoot());
}

Use the plugin

Simply bind an array to virtual-repeat like you would with the standard repeat. The repeated rows need to have equal height throughout the list, and one items per row.

div

<template>
  <div virtual-repeat.for="item of items">
    ${$index} ${item}
  </div>
</template>

unordered list

<template>
  <ul>
    <li virtual-repeat.for="item of items">
    ${$index} ${item}
    </li>
  </ul>
</template>

table

<template>
  <table>
    <tr virtual-repeat.for="item of items">
      <td>${$index}</td>
      <td>${item}</td>
    </tr>
  </table>
</template>
export class MyVirtualList {
    items = ['Foo', 'Bar', 'Baz'];
}

With a surrounding fixed height container with overflow scroll. Note that overflow: scroll styling is inlined on the elemenet. It can also be applied from CSS.

<template>
  <div style="overflow: scroll; height: 90vh">
    <div virtual-repeat.for="item of items">
      ${$index} ${item}
    </div>
  </div>
</template>

If you are running the plugin in the skeleton-naviagion project, make sure to remove overflow-x: hidden; and overflow-y: auto; from .page-host in styles.css.

infinite scroll

<template>
  <div virtual-repeat.for="item of items" infinite-scroll-next="getMore">
    ${$index} ${item}
  </div>
</template>
export class MyVirtualList {
  items = ['Foo', 'Bar', 'Baz'];
  getMore(topIndex, isAtBottom, isAtTop) {
    for(let i = 0; i < 100; ++i) {
      this.items.push('item' + i);
    }
  }
}

Or to use an expression, use .call as shown below.

<template>
  <div virtual-repeat.for="item of items" infinite-scroll-next.call="getMore($scrollContext)">
    ${$index} ${item}
  </div>
</template>
export class MyVirtualList {
  items = ['Foo', 'Bar', 'Baz'];
  getMore(scrollContext) {
    for(let i = 0; i < 100; ++i) {
      this.items.push('item' + i);
    }
  }
}

The infinite-scroll-next attribute can accept a function, a promise, or a function that returns a promise. The bound function will be called when the scroll container has reached a point where there are no more items to move into the DOM (i.e. when it reaches the end of a list, either from the top or the bottom).

There are three parameters that are passed to the function (getMore(topIndex, isAtBottom, isAtTop)) which helps determine the behavior or amount of items to get during scrolling.

  1. topIndex - A integer value that represents the current item that exists at the top of the rendered items in the DOM.
  2. isAtBottom - A boolean value that indicates whether the list has been scrolled to the bottom of the items list.
  3. isAtTop - A boolean value that indicates whether the list has been scrolled to the top of the items list.

Caveats

  1. <template/> is not supported as root element of a virtual repeat template. This is due to the requirement of aurelia ui virtualization technique: item height needs to be calculatable. With <tempate/>, there is no easy and performant way to acquire this value.
  2. Similar to (1), other template controllers cannot be used in conjunction with virtual-repeat, unlike repeat. I.e: built-in template controllers: with, if, replaceable cannot be used with virtual-repeat. This can be workaround'd by nesting other template controllers inside the repeated element, with <template/> element, for example:
<template>
  <h1>${message}</h1>
  <div virtual-repeat.for="person of persons">
    <template with.bind="person">
      ${Name}
    </template>
  </div>
</template>
  1. Beware of CSS selector :nth-child and similar selectors. Virtualization requires appropriate removing and inserting visible items, based on scroll position. This means DOM elements order will not stay the same, thus creating unexpected :nth-child CSS selector behavior. To work around this, you can use contextual properties $index, $odd, $even etc... to determine an item position, and apply CSS classes/styles against it, like the following example:
<template>
  <div virtual-repeat.for="person of persons" class="${$odd ? 'odd' : 'even'}-row">
    ${person.name}
  </div>
</template>
  1. Similar to (3), virtualization requires appropriate removing and inserting visible items, corresponding lifecycle of items view will also be triggered while inserting (bind, attached) or removing (unbind, detached)

Demo

Online Playground

Platform Support

This library can be used in the browser only.

Building The Code

To build the code, follow these steps.

  1. Ensure that NodeJS is installed. This provides the platform on which the build tooling runs.
  2. From the project folder, execute the following command:
npm install
  1. To build the code, you can now run:
npm run build
  1. You will find the compiled code in the dist folder, available in module formats: es2015, es2017, AMD, CommonJS and UMD.

Running The Tests

To run the unit tests, first ensure that you have followed the steps above in order to install all dependencies and successfully build the library. Once you have done that, proceed with these additional steps:

  1. Run the tests with this command:
npm run test
You can’t perform that action at this time.