首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >以对象为观察者的观察者模式

以对象为观察者的观察者模式
EN

Stack Overflow用户
提问于 2021-06-21 07:11:45
回答 1查看 69关注 0票数 0

我使用函数作为观察者实现了观察者模式,它的工作方式似乎与预期的一样:

代码语言:javascript
复制
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);
  });
}
代码语言:javascript
复制
<!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输入元素连接起来。我想到了一个像这样的构造函数:

代码语言:javascript
复制
function Observer() {
  this.notify = function (subject) {
    let currentState = subject.getState();
    this.value = currentState;
    console.log(currentState);        // logs current state (testing)
  }
}

以及Subject中的一个方法,如下所示:

代码语言:javascript
复制
Subject.prototype.getState = function () {
  return this._state;
}

但是,我无法理解如何将输入元素(observerOneElemobserverTwoElem)与Observer实例连接起来。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-06-21 11:51:42

这并不难,只需在实例化Observer观察者时通过传递id来选择构造函数中的元素。现在,它与作为对象实现的观察者一起工作。(没有幼犬受到伤害,也没有咨询图书馆)

代码语言:javascript
复制
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;
  }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68063754

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档