An efficient incremental rendering list view for large lists.
Ember.ListView
works on major modern browsers and also on major mobile devices (iOS, Android).
However, there are known issues with using Ember.ListView
on mobile web (if you have a long list
and you're touch-scrolling it very fast, you'll see that items in your list start to disappear
and after some lag appear again). That happens because mobile browsers do not emit scroll events
during the momentum scroll phase that Ember.ListView
needs to capture.
If you want to have something running on mobile, please make sure to use Ember.VirtualListView
,
which behaves exactly the same (in terms of configuration and working with it) as Ember.ListView
.
However, note that Ember.VirtualListView
doesn't have a native scroll bar. This is something that
we need to work on for future releases of Ember.ListView
.
Both Ember.ListView
and Ember.VirtualListView
need jquery,
handlebars, ember.js.
Ember.VirtualListView
need an additional dependency: zynga scroller.
Please, take a look at our live demo and jsbin links: first and second.
Please, attach code samples or links to jsbin or jsfiddle. It would help us greatly to help you and to improve ember list view.
First, let's create a template:
<script type="text/x-handlebars" data-template-name="index">
{{#collection Ember.ListView contentBinding="controller" height=500 rowHeight=50 width=500}}
{{name}}
{{/collection}}
</script>
Next, let's feed our template with some data:
// create Ember application
App = Ember.Application.create();
// create Ember.ArrayController
App.IndexController = Ember.ArrayController.extend({
content: []
});
// define default index route and pushing some data to content
App.IndexRoute = Ember.Route.extend({
setupController: function(controller) {
var content = [];
for (var i = 0; i < 10000; i++) {
content.push({name: "Item " + i});
}
controller.set('content', content);
}
});
Shazam! You should be able to see a scrollable area with 10,000 items in it.
Here's an example of how to create your version of Ember.ListView
.
<script type="text/x-handlebars" data-template-name="index">
{{view App.ListView contentBinding="controller"}}
</script>
<script type="text/x-handlebars" data-template-name="row_item">
{{name}}
</script>
// create Ember application
App = Ember.Application.create();
// define default index route and pushing some data to content
App.IndexRoute = Ember.Route.extend({
setupController: function(controller) {
var content = [];
for (var i = 0; i < 10000; i++) {
content.push({name: "Item " + i});
}
controller.set('content', content);
}
});
// extending Ember.ListView
// customize the row views by subclassing Ember.ListItemView
// and specifying the itemViewClass property in the Ember.ListView definition
App.ListView = Ember.ListView.extend({
height: 500,
rowHeight: 50,
itemViewClass: Ember.ListItemView.extend({templateName: "row_item"})
});
Unfortunately, if you want to customize item template, you would have to use Ember.ListItemView
and create an additional template, as you see above. You cannot specify templateName
paramter
directly on Ember.ListView
because it's derived from Ember.ContainerView
and it cannot have a template.
The height and width of the entire Ember.ListView
can be adjusted at run-time.
When this occurs the Ember.ListView
will transform existing view items to the new locations,
and create and position any new view items that might be needed.
This is meant to make resizing as cheap as possible.
App.ListView = Ember.ListView.extend({
height: 500,
width: 960,
adjustLayout: function(new_width, new_height) {
this.set('width', new_width);
this.set('height', new_height);
}
});
You must specify the height
and rowHeight
parameters because Ember.ListView
will try
to fill visible area with rows. If you would like to have multiple columns, then you need to specify
elementWidth
, as well as width
.
App.ListView = Ember.ListView.extend({
height: 500,
rowHeight: 50,
elementWidth: 80,
width: 500,
itemViewClass: Ember.ListItemView.extend({templateName: "row_item"})
});
.ember-list-view {
overflow: auto;
position: relative;
}
.ember-list-item-view {
position: absolute;
}
git clone https://github.com/emberjs/list-view.git
bundle
bundle exec rake dist
cp dist/modules/list-view.js mycoolapp/
Ember.ListView
will create enough rows to fill the visible area (as defined by the height
property). It reacts to scroll events and reuses/repositions the rows as scrolled.
Please look at the unit tests for more information.
Run bundle exec rackup
and open http://localhost:9292 in a browser.
Things we are aware about and are on the list to fix.
classNameBindings
andattributeBindings
won't work properly onListItemView
after view's recycle. Using it should be avoided. Demo.
A lot of the work was sponsored by Yapp Labs.