Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/mysterlune/ember-cli-sparse-array
An EmberCLI addon sparse array implementation.
https://github.com/mysterlune/ember-cli-sparse-array
Last synced: 7 days ago
JSON representation
An EmberCLI addon sparse array implementation.
- Host: GitHub
- URL: https://github.com/mysterlune/ember-cli-sparse-array
- Owner: mysterlune
- License: mit
- Created: 2015-06-19T21:52:49.000Z (over 9 years ago)
- Default Branch: master
- Last Pushed: 2015-06-27T04:04:01.000Z (over 9 years ago)
- Last Synced: 2024-04-15T03:19:35.921Z (9 months ago)
- Language: JavaScript
- Size: 138 KB
- Stars: 0
- Watchers: 2
- Forks: 3
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
Awesome Lists containing this project
README
# EmberCLI Sparse Array Addon
An implementation of [SparseArray]() for Ember.js configured as an addon so that you may use it in any of your EmberCLI projects.
## Installation
````
ember install ember-cli-sparse-array
ember g emer-cli-sparse-array
````This will create an addon namespace for your application, 'ember-cli-sparse-array'. Available in this namespace is a `lib/sparse-array`, which gives your code an array definition to work with.
## Usage
````
import Ember from 'ember';
import SparseArray from 'ember-cli-sparse-array/lib/sparse-array';export default SparseArray.extend({
// Implement your `load` callback ;)
})
````You can return the sparse array to a route's `model` hook (or `afterModel` or `beforeModel` depending on your needs) if you wish your route's controller's model to be the content of a lazy-loadable sparse array.
You can use the a route's `...controllerFor('my_route').set('model', mySparseArray);` to do your bidding... You just neet do implement the `load` callback.
## Instantiating a SparseArray
When instantiating a `SparseArray`, you have to supply a `load` method. The `load` method is responsible for fetching a subset of the resource, e.g. from your server.
The `load` method must accept two arguments:
- `offset`: The 0-based index/offset of the first record to be fetched.
- `limit`: How many records should be fetchedThe `load` method must return a thenable (i.e. a promise or another object with a `.then` method on it) that eventually resolves with a hash with two keys:
- `total`: The total number of records.
- `items`: An array of maximum `limit` items that start at `offset`.Here is an example:
```javascript
var SparseArray = require('ember-cli-sparse-array/lib/sparse-array');var comments = SparseArray.create({
load: function(offset, limit) {
return new Em.RSVP.Promise(function(resolve) {
$.getJSON('/comments?offset='+offset+'&limit='+limit).then(function(payload) {
resolve({
total: payload.meta.total,
items: payload.comments
});
});
});
}
});
```The `SparseArray` will automatically call your `load` method when items at not-yet-loaded indexes are being requested by your application.
## Using a SparseArray
The `length` attribute of your `SparseArray` works just like a normal array. It will start out as `0`. It will be set to the value of `total` each time a promise from `load` resolves.
`load` is always called instantly with `offset` being `0` when you instantiate a `SparseArray`. This is to find the `length` property right away.
The `SparseArray` also has a property called `isLoaded`, which is `false` until the first time a `load` completes, where it will be set to `true`, and stay `true` forever.
Calling `.objectAt` at an index that's greater than or equals to the current `length`, will always return `null`.
Example:
````
var comments = SparseArray.create({
load: function(offset, limit) {/* ... */}
});
comments.get('length'); //Will always be 0, since the data hasn't been loaded yet
comments.get('isLoaded'); //false
comments.objectAt(0); //null
comments.objectAt(9999999); //null//Later, after the first load has completed:
comments.get('length'); //The `total` value that you resolved the promise with
comments.get('isLoaded'); //true
comments.objectAt(0); //Whatever you returned at the index 0
````After the `load` method has completed at least once, and the array has a `length` property, requesting an index less than `length`, will make the array fetch the items around that index using the `load` method, if the `index` has not
been loaded yet.## Notice about using {{each}} and other eager consumers
The `{{each}}` Handlebars helper is "eager", meaning that it will insert views for _all_ items right away. So when your
load promise resolves with a `total` value of 9000, it will create 9000 views right away, and request each of the 9000
items from your array. This may result in _a lot_ of requests.The real power of sparse arrays is when using them together with container views that only requests (i.e. calls
`.objectAt`) items that is supposed to be in the browser's current viewport. A good example is
[Ember.ListView](https://github.com/emberjs/list-view) (disclaimer: This sparse array implementation has not been tested
with Ember.ListView yet, but you get the idea).## Options
You can set other options than the `load` method when instantiating `SparseArray`. Example:
```javascript
SparseArray.create({
batchSize: 42,
load: function() {/* ... */}
});
```The following options are supported:
- `batchSize` (integer): The maximum number of records the sparse array will ask the `load` method to load through the `limit`
argument. The actual value of `limit` may be lower, since the sparse array will only load items that have not already
been loaded. Defaults to `100`.## Known limitations
- Rejected promises from the `load` method are currently not handled.
- Short lists (length of 1 or 2) are not the best use of this.
- Lists where the last object is on its own "page" will never load the last page (because the `objectAt` logic is difficult).## Contriubte
Fork and PR :)
Above in "Known limitations" is a good place to start picking up issues.