Skip to content

Instantly share code, notes, and snippets.

@jsobell
Created August 1, 2018 22:46

Revisions

  1. jsobell revised this gist Aug 1, 2018. No changes.
  2. jsobell created this gist Aug 1, 2018.
    7 changes: 7 additions & 0 deletions app.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,7 @@
    <template>
    <ul href="#!" repeat.for="user of users">
    <li>
    <input value.bind='user.firstName' /> <input value.bind='user.lastName' />
    </li>
    </ul>
    </template>
    67 changes: 67 additions & 0 deletions app.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,67 @@
    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 [];
    }
    }
    17 changes: 17 additions & 0 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,17 @@
    <!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>
    18 changes: 18 additions & 0 deletions styles.css
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,18 @@
    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;
    }