Skip to content

Instantly share code, notes, and snippets.

@jsobell
Created August 1, 2018 22:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jsobell/cfca52cd421be1e0bb6f9da9cb2cbe16 to your computer and use it in GitHub Desktop.
Save jsobell/cfca52cd421be1e0bb6f9da9cb2cbe16 to your computer and use it in GitHub Desktop.
Simple change detector example
<template>
<ul href="#!" repeat.for="user of users">
<li>
<input value.bind='user.firstName' /> <input value.bind='user.lastName' />
</li>
</ul>
</template>
export class App {
users = [
{ id: 1, firstName: 'Rob', lastName: 'Eisenberg' },
{ id: 2, firstName: 'Jeremy', lastName: 'Danyow' },
{ id: 3, firstName: 'Matt', lastName: 'Broadst' }];
selectUser(userId) {
let user = this.users.find(u => u.id == userId);
user.state = 'active';
}
activate() {
var cd = new ChangeDetector();
cd.observe(this, 'users', (to,from,property)=>console.log({ to,from,property }));
}
}
export class ChangeDetector {
constructor() {
}
observe(target, property, callback, checkspersecond) {
var subscription = { timer:{}, target, property, previous:{} };
subscription.timer = setInterval(() => this.compare(subscription, callback) , 1000/(checkspersecond || 7));
return () => { clearInterval(subscription.timer); }
}
compare(subscription:any, callback) {
let s=subscription.target[subscription.property];
let path = 'this';
var diffs = this.finddiff(s, subscription.previous,0,path);
if (diffs[0]) { callback(diffs[2], diffs[1], diffs[0] ); }
subscription.previous = JSON.parse(JSON.stringify(s)) ;
}
finddiff = function(previous,current, depth, path){
let isarray = (current instanceof Array);
for (var p in current) {
if(typeof(current[p]) !== typeof(previous[p])) return [path+'.'+p,current[p] , previous[p]];
if((current[p]===null) !== (previous[p]===null)) return [path+'.'+p,current[p],previous[p]];
switch (typeof(current[p])) {
case 'undefined':
if (typeof(previous[p]) != 'undefined') return [path+'.'+p,undefined,previous[p]];
break;
case 'object':
if(current[p]!==null && previous[p]!==null
&& (current[p].constructor.toString() !== previous[p].constructor.toString()))
return [path+'.'+p, current[p], previous[p]];
let nested = this.finddiff(previous[p],current[p], depth+1, path + (isarray ? '[' : '.') + p + (isarray ? ']' : ''));
if(!!nested.length) return nested;
break;
case 'function':
if (p != 'equals' && current[p].toString() != previous[p].toString()) return [path+'.'+p, current[p],previous[p]];
break;
default:
if (current[p] !== previous[p]) return [path+'.'+p, current[p], previous[p]];
}
}
return [];
}
}
<!doctype html>
<html>
<head>
<title>Aurelia</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles.css">
</head>
<body aurelia-app>
<h1>Loading...</h1>
<script src="https://cdn.rawgit.com/jdanyow/aurelia-bundle/v1.0.3/jspm_packages/system.js"></script>
<script src="https://cdn.rawgit.com/jdanyow/aurelia-bundle/v1.0.3/config.js"></script>
<script>
System.import('aurelia-bootstrapper');
</script>
</body>
</html>
a {
display: block;
}
a:link {
color: black;
text-decoration: none;
}
.collection-item
{
background: lightgray;
}
/* since you set background property on .collection-item, this style must come after .collection-item otherwise it's not applied */
.active {
background: blue;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment