minte9
LearnRemember



Application

When App property changes observers are notified.

index.htm

 
<form>
    <input type='button' id='clickButton' value='Click'>
    <input type='button' id='undoButton' value='Undo'>
    <input type='button' id='resetButton' value='Reset'>
    <br><br>
    Clicks <input type='text' id='clicks' size=2>
    <br><br>
    Undos <input type='text' id='undos' size=2>
</form>

app.js

 
document.addEventListener("DOMContentLoaded", 
    function() {
        app = new App();
        app.init();
    }
);

class Subject {
  constructor() {
    this.observers = [];
  }

  addObserver(observer) {
    this.observers.push(observer);
  }

  removeObserver(observer) {
    this.observers = this.observers.filter(
        value => value !== observer
    );
  }

  notifyObservers() {
    this.observers.forEach((observer) => observer.update());
  }
}

class Observer {
  update() {
    console.log(this.constructor.name + " must implement update()");
  }
}


class App extends Subject {
  constructor() {
    super();

    this.clicks = 0;
    this.undos = 0;
  }

  init() {
    app.addObserver(new ClicksClass());
    app.addObserver(new UndosClass());
    app.addObserver(new ResetClass());
  }
}


class ClicksClass extends Observer {
  constructor() {
    super();

    document.getElementById("clickButton").
    addEventListener("click", function() {
      app.clicks++;
      app.notifyObservers();
    });
  }

  update() {
    document.getElementById("clicks").value = app.clicks;
  }
}

class UndosClass extends Observer {
  constructor() {
    super();

    document.getElementById("undoButton").
    addEventListener("click", function() {
      app.undos++;
      app.clicks = app.clicks > 0 ? app.clicks - 1 : 0;
      app.notifyObservers();
    });
  }

  update() {
    document.getElementById("undos").value = app.undos;
  }
}

class ResetClass extends Observer {
  constructor() {
    super();

    document.getElementById("resetButton").
    addEventListener("click", function() {
      app.undos = 0;
      app.clicks = 0;
      app.notifyObservers();
    });
  }
}

Update props

Update Object properties when Subject changes.
 
class Subject
{
    ...

    notifyObservers()
    {
        this.observers.forEach(function(observer) {
            observer.updateProps(this);
            observer.update();
        }.bind(this));
    }
}


class Observer
{
    updateProps(subject)
    {
        const props = Object.getOwnPropertyNames(subject);

        for (const key of props) {
            this[key] = subject[key];
        }
    }

    update()
    {
        console.log(
            this.constructor.name + " must implement update()"
        );
    }
}



  Last update: 432 days ago