Skip to content

Instantly share code, notes, and snippets.

@niieani
Last active April 19, 2016 10:26
Show Gist options
  • Save niieani/499ef4b8b871105deb9fdf597e47265d to your computer and use it in GitHub Desktop.
Save niieani/499ef4b8b871105deb9fdf597e47265d to your computer and use it in GitHub Desktop.
Aurelia: Suboptimal repeat element lifecycle [alternative without compose + diff]
<template>
<require from="./component"></require>
<input type="checkbox" ref="isFiltering">
<br>
<component
repeat.for="id of components | without8: isFiltering.checked | diff"
id.bind="id"
></component>
</template>
import {transient} from 'aurelia-framework'
import {Component} from './component'
export class App {
constructor() {
this.components = []
for (let i = 0; i <= 9; i++) {
this.components.push(i)
}
}
}
export class Without8ValueConverter {
toView(array, isEnabled) {
return isEnabled ? array.filter(element => element !== 8) : array
}
}
@transient()
export class DiffValueConverter {
previousInstance;
proxy;
toView(array) {
// TODO: should to add GetRepeatStrategy to observe and proxy the mutations from the underlying array too
if (!this.proxy) {
this.proxy = array.slice(0)
this.previousInstance = array
}
else if (this.previousInstance !== array) {
//diff
const removedIndicies = []
this.proxy.forEach((element, index) => {
const newIndex = array.indexOf(element)
if (newIndex === -1) {
removedIndicies.push(index)
}
})
if (removedIndicies.length) {
multisplice(this.proxy, ...removedIndicies)
console.log('removed no longer needed indicies:', removedIndicies)
}
// add missing
array.forEach((element, index) => {
const oldIndex = this.proxy.indexOf(element)
if (oldIndex === -1) {
// new element missing in old array, add it
this.proxy.splice(index, 0, element)
console.log('adding index:', index, 'element', element)
}
else if (oldIndex !== index) {
// element changed place, remove it
// (it'll be added again once we iterate its proper index)
this.proxy.splice(index, 1)
console.log('changed place, removing index:', index, 'element', element)
} else {
// element didn't change positions
}
})
this.previousInstance = array
}
console.log('the array is currently:', this.proxy)
return this.proxy
}
}
// http://upshots.org/actionscript/javascript-splice-array-on-multiple-indices-multisplice
function multisplice(array /*, ...args */){
var args = Array.apply(null, arguments).slice(1);
args.sort(function(a, b){
return a - b;
});
for(var i = 0; i < args.length; i++){
var index = args[i] - i;
array.splice(index, 1);
}
}
import {inlineView, bindable} from 'aurelia-framework'
@inlineView('<template>${id}<br></template>')
export class Component {
@bindable id
bind() {
console.log('bind', this.id)
}
unbind() {
console.log('unbind', this.id)
}
}
<!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