Skip to content

Instantly share code, notes, and snippets.

@silverbucket
Forked from jdanyow/app.html
Last active June 29, 2016 12:56
Show Gist options
  • Save silverbucket/9538acd77d0403da3c691fad6149c63a to your computer and use it in GitHub Desktop.
Save silverbucket/9538acd77d0403da3c691fad6149c63a to your computer and use it in GitHub Desktop.
Aurelia - rewriting arrays UI update failure
<template>
<h1>Files List</h1>
<button click.trigger="addFile()">Add File</button>
<ul>
<li repeat.for="file of files._store">
<p>${file.uid} - ${file.name}</p>
</li>
</ul>
</template>
export class App {
message = 'Hello World!';
constructor() {
this.files = new ArrayKeys({
identifier: 'uid'
});
}
addFile() {
var uid = makeid(5);
console.log('adding file: ' + uid);
var file = {
uid: uid,
name: 'filename-' + uid
};
this.files.addRecord(file);
console.log('files: ', this.files._store);
}
}
function makeid(count) {
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (var i = 0; i < count; i++) {
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
return text;
}
function ArrayKeys(p) {
if (typeof p !== 'object') { p = {}; }
this._identifier = p.identifier || 'id';
this._store = [];
this._idx = []; // array of identifier strings for quick lookup
this._emitEvents = false;
}
ArrayKeys.prototype.emitEvent = function (event, data, dontEmit) {
if ((this._emitEvents) && (! dontEmit)) {
this.events.emit(event, data);
}
};
ArrayKeys.prototype.getIdentifiers = function () {
var ids = [];
for (var i = this._store.length - 1; i >= 0; i = i - 1) {
ids[ids.length] = this._store[i][this._identifier];
}
return ids;
};
ArrayKeys.prototype.getRecord = function (id) {
for (var i = this._store.length - 1; i >= 0; i = i - 1) {
if (this._store[i][this._identifier] === id) {
return this._store[i];
}
}
return undefined;
};
ArrayKeys.prototype.exists = function (id) {
if (this.getIndex(id) >= 0) {
return true;
} else {
return false;
}
};
// faster than using indexOf
ArrayKeys.prototype.getIndex = function (id) {
for (var i = this._idx.length - 1; i >= 0; i = i - 1) {
if (this._idx[i] === id) {
return i;
}
}
return -1;
};
ArrayKeys.prototype.addRecord = function (record) {
if (typeof record !== 'object') {
throw new Error('cannot add non-object records.');
} else if (!record[this._identifier]) {
throw new Error('cannot add a record with no `' + this._identifier +
'` property specified.');
}
var removed = this.removeRecord(record[this._identifier], true);
this._idx[this._idx.length] = record[this._identifier];
this._store[this._store.length] = record;
setTimeout(function () {
if (removed) {
setTimeout(this.emitEvent.bind(this, 'update', record), 0);
} else {
setTimeout(this.emitEvent.bind(this, 'add', record), 0);
}
}.bind(this), 0);
return true;
};
ArrayKeys.prototype.removeRecord = function (id, dontEmit) {
var idx = this.getIndex(id);
if (idx < 0) {
return false;
}
// start looking for the record at the same point as the idx entry
for (var i = idx; i >= 0; i = i - 1) {
if ((this._store[i]) && (this._store[i][this._identifier] === id)) {
this._store.splice(i, 1);
this._idx.splice(idx, 1);
setTimeout(this.emitEvent.bind(this, 'remove', id, dontEmit), 0);
return true;
}
}
// if it was not found, start at the end and break at the idx number
for (var n = this._store.length - 1; n >= idx; n = n - 1) {
if ((this._store[i]) && (this._store[n][this._identifier] === id)) {
this._store.splice(n, 1);
this._idx.splice(idx, 1);
setTimeout(this.emitEvent.bind(this, 'remove', id, dontEmit), 0);
return true;
}
}
return false;
};
ArrayKeys.prototype.forEachRecord = function (cb) {
var count = 0;
var self = this;
var finished = function () {};
setTimeout(function () {
for (var i = self._store.length - 1; i >= 0; i = i - 1) {
count += 1;
setTimeout(cb(self._store[i]), 0);
}
setTimeout(finished(count), 0);
}, 0);
return {
finally: function (func) {
finished = func;
}
};
};
ArrayKeys.prototype.getCount = function () {
return this._store.length;
};
ArrayKeys.prototype.removeAll = function () {
for (var i = this._store.length - 1; i >= 0; i = i - 1) {
delete this._store[i];
}
this._store = [];
};
<!doctype html>
<html>
<head>
<title>Aurelia</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body aurelia-app>
<h1>Loading...</h1>
<script src="https://jdanyow.github.io/rjs-bundle/node_modules/requirejs/require.js"></script>
<script src="https://jdanyow.github.io/rjs-bundle/config.js"></script>
<script src="https://jdanyow.github.io/rjs-bundle/bundles/aurelia.js"></script>
<script src="https://jdanyow.github.io/rjs-bundle/bundles/babel.js"></script>
<script>
require(['aurelia-bootstrapper']);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment