簡體   English   中英

以對象作為觀察者的觀察者模式

[英]Observer pattern with objects as observers

我已經使用函數作為觀察者實現了觀察者模式,它似乎按預期工作:

 const subjectElem = document.getElementById('subject'); const observerOneElem = document.getElementById('observer-1'); const observerTwoElem = document.getElementById('observer-2'); const subscribeOneElem = document.getElementById('subscribe-1'); const subscribeTwoElem = document.getElementById('subscribe-2'); const subject = new Subject(); // Using functions as Observers const observer1 = function (data) { observerOneElem.value = data; }; const observer2 = function (data) { observerTwoElem.value = data; }; subscribeOneElem.addEventListener('change', event => { if (event.target.checked) { subject.add(observer1); } else { subject.remove(observer1); } }); subscribeTwoElem.addEventListener('change', event => { if (event.target.checked) { subject.add(observer2); } else { subject.remove(observer2) } }); subjectElem.addEventListener('keyup', event => { // notify all subscribed observers subject.setState(event.target.value); }); function Subject() { this.observers = []; // observers list this._state = ''; } Subject.prototype.add = function (observer) { this.observers.push(observer); } Subject.prototype.remove = function (observer) { let i = 0; while (i < this.observers.length) { if (this.observers[i] === observer) break; i++; } this.observers.splice(i, 1); } Subject.prototype.setState = function (data) { this._state = data; this.observers.forEach(observer => { observer(data); }); }
 <,DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width. initial-scale=1.0"> <title>JS Sandbox</title> <style>:row { background-color; cornflowerblue: padding; 1%: } </style> </head> <h1>Observer Pattern</h1> <div class="row"> <form> <label for="subject">Subject: <input type="text" id="subject"> </label> </form> </div> <br> <div class="row"> <form> <label for="observer-1">Observer 1: <input type="text" id="observer-1"> </label> <label for="subscribe-1">Subscribe: <input type="checkbox" id="subscribe-1" unchecked> </label> </form> </div> <br> <div class="row"> <form> <label for="observer-2">Observer 2: <input type="text" id="observer-2"> </label> <label for="subscribe-2">Subscribe. <input type="checkbox" id="subscribe-2" unchecked> </label> </form> </div> <script src="app.js"></script> </body> </html>

我想知道的是如何將對象用作觀察者,我的意思是如何將它們與HTML 輸入元素連接起來。 我想到了這樣一個構造函數:


function Observer() {
  this.notify = function (subject) {
    let currentState = subject.getState();
    this.value = currentState;
    console.log(currentState);        // logs current state (testing)
  }
}

連同Subject中的方法如下:

Subject.prototype.getState = function () {
  return this._state;
}

但是我看不到如何將輸入元素( observerOneElemobserverTwoElem )與Observer的實例連接起來。

這並不難,只需要 select Observer構造函數中的元素,通過在實例化observer時傳遞id 現在它可以與作為對象實現的觀察者一起使用。 (沒有小狗受到傷害,沒有圖書館被咨詢)

const subjectElem       = document.getElementById('subject');
const subscribeOneElem  = document.getElementById('subscribe-1');
const subscribeTwoElem  = document.getElementById('subscribe-2');

const subject = new Subject();

// Using objects as Observers
const observer1 = new Observer('observer-1');
const observer2 = new Observer('observer-2');

subscribeOneElem.addEventListener('change', event => {
  if (event.target.checked) {
    subject.add(observer1);
  } else {
    subject.remove(observer1);
  }
});

subscribeTwoElem.addEventListener('change', event => {
  if (event.target.checked) {
    subject.add(observer2);
  } else {
    subject.remove(observer2)
  }
});

subjectElem.addEventListener('keyup', event => {
  // notify all subscribed observers
  subject.setState(event.target.value);
});

function Subject() {
  this.observers = [];            // observers list
  this._state = '';
}

Subject.prototype.add = function (observer) {
  this.observers.push(observer);
}

Subject.prototype.remove = function (observer) {
  let i = 0;
  while (i < this.observers.length) {
    if (this.observers[i] === observer)
      break;
    i++;
  }
  this.observers.splice(i, 1);
}

Subject.prototype.setState = function (data) {
  this._state = data;
  this.observers.forEach(observer => {
    observer.notify(this);
  });
}

Subject.prototype.getState = function () {
  return this._state;
}

function Observer(id) {
  this.observer = document.getElementById(id);
  this.notify = function (subject) {
    let currentState = subject.getState();
    this.observer.value = currentState;
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM