mercredi 23 mars 2022

Javascript design pattern publish-subscribe

I'm learning and practicing Javascript publish-subscribe design pattern.

Here is the code: https://codesandbox.io/s/javascript-forked-5vb602?file=/index.js.

What my issue is, when I want to calculate the most expensive unit, when the previous most expensive unit change to 0, I don't know how to find a new highest unit value.

On the most-expensive-minus, I can only find the corresponding unit price, but not others. So how can I find other values?

This is the whole code:

HTML:

<div id="root">
  <div id="box">
    <ul>
      <li>
        <input type="button" value="-" />
        <span class="num">0</span>
        <input type="button" value="+" />
        <span>single price:</span>
        $<span class="unit">15;</span>
        <span class="label">total:</span>
        $<span class="subtotal">0</span>
      </li>
      <li>
        <input type="button" value="-" />
        <span class="num">0</span>
        <input type="button" value="+" />
        <span>single price:</span>
        $<span class="unit">10;</span>
        <span class="label">total:</span>
        $<span class="subtotal">0</span>
      </li>
      <li>
        <input type="button" value="-" />
        <span class="num">0</span>
        <input type="button" value="+" />
        <span>single price:</span>
        $<span class="unit">5;</span>
        <span class="label">total:</span>
        $<span class="subtotal">0</span>
      </li>
      <li>
        <input type="button" value="-" />
        <span class="num">0</span>
        <input type="button" value="+" />
        <span>single price:</span>
        $<span class="unit">2;</span>
        <span class="label">total:</span>
        $<span class="subtotal">0</span>
      </li>
      <li>
        <input type="button" value="-" />
        <span class="num">0</span>
        <input type="button" value="+" />
        <span>single price:</span>
        $<span class="unit">1;</span>
        <span class="label">total:</span>
        $<span class="subtotal">0</span>
      </li>
    </ul>
    <div class="total-box">
      total purchase
      <span id="goods-num">0</span>
      ; total cost $
      <span id="total-price">0</span>
      ; most expensieve single one is $<span id="unit-price">0</span>
    </div>
  </div>
</div>

Javascript:

const Event = {
  userList: {},
  subscribe(key, fn) {
    if (!this.userList[key]) {
      this.userList[key] = [];
    }
    this.userList[key].push(fn);
  },
  publish() {
    const key = Array.prototype.shift.apply(arguments);
    const fns = this.userList[key];
    if (!fns || fns.length === 0) {
      return false;
    }
    for (let i = 0, len = fns.length; i < len; i++) {
      fns[i].apply(this, arguments);
    }
  }
};
(function () {
  const aBtnMinus = document.querySelectorAll("#box li>input:first-child");
  const aBtnPlus = document.querySelectorAll("#box li>input:nth-of-type(2)");
  const oTotalPrice = document.querySelector("#total-price");
  const oUnitPrice = document.querySelector("#unit-price");
  let curUnitPrice = 0;

  for (let i = 0, len = aBtnMinus.length; i < len; i++) {
    aBtnMinus[i].index = aBtnPlus[i].index = i;
    aBtnMinus[i].onclick = function () {
      this.parentNode.children[1].innerHTML > 0 &&
        Event.publish("total-goods-num-minus");
      --this.parentNode.children[1].innerHTML < 0 &&
        (this.parentNode.children[1].innerHTML = 0);
      curUnitPrice = this.parentNode.children[4].innerHTML;
      Event.publish(
        `minus-num${this.index}`,
        parseInt(curUnitPrice),
        parseInt(this.parentNode.children[1].innerHTML)
      );
      Event.publish(
        `total-minus`,
        parseInt(curUnitPrice),
        parseInt(this.parentNode.children[1].innerHTML),
        parseInt(oTotalPrice.innerHTML)
      );
      Event.publish(
        `most-expensive-minus`,
        parseInt(curUnitPrice),
        parseInt(this.parentNode.children[1].innerHTML),
        parseInt(oUnitPrice.innerHTML)
      );
    };
    aBtnPlus[i].onclick = function () {
      this.parentNode.children[1].innerHTML >= 0 &&
        Event.publish("total-goods-num-plus");
      this.parentNode.children[1].innerHTML++;
      curUnitPrice = this.parentNode.children[4].innerHTML;
      Event.publish(
        `plus-num${this.index}`,
        parseInt(curUnitPrice),
        parseInt(this.parentNode.children[1].innerHTML)
      );
      Event.publish(
        `total-plus`,
        parseInt(curUnitPrice),
        parseInt(this.parentNode.children[1].innerHTML),
        parseInt(oTotalPrice.innerHTML)
      );
      Event.publish(
        `most-expensive-plus`,
        parseInt(curUnitPrice),
        parseInt(oUnitPrice.innerHTML)
      );
    };
  }
})();
(function () {
  const aSubtotal = document.querySelectorAll("#box .subtotal");
  const oGoodsNum = document.querySelector("#goods-num");
  const oTotalPrice = document.querySelector("#total-price");
  const oUnitPrice = document.querySelector("#unit-price");

  Event.subscribe("total-goods-num-plus", function () {
    ++oGoodsNum.innerHTML;
  });
  Event.subscribe("total-goods-num-minus", function () {
    --oGoodsNum.innerHTML;
  });
  Event.subscribe(`total-plus`, function (unitPrice, num, originalPrice) {
    oTotalPrice.innerHTML =
      originalPrice - unitPrice * (num - 1) + unitPrice * num;
  });
  Event.subscribe(`total-minus`, function (unitPrice, num, originalPrice) {
    if (num > 0)
      oTotalPrice.innerHTML =
        originalPrice + unitPrice * (num - 1) - unitPrice * num;
  });
  Event.subscribe(`most-expensive-plus`, function (
    unitPrice,
    originalMostExpensive
  ) {
    oUnitPrice.innerHTML =
      originalMostExpensive < unitPrice ? unitPrice : originalMostExpensive;
  });
  Event.subscribe(`most-expensive-minus`, function (
    unitPrice,
    num,
    originalMostExpensive
  ) {
    if (num > 0) {
      oUnitPrice.innerHTML =
        originalMostExpensive < unitPrice ? unitPrice : originalMostExpensive;
    } else {
      oUnitPrice.innerHTML = "xx"; //how to find the new highest price?;
    }
  });
  for (let i = 0, len = aSubtotal.length; i < len; i++) {
    Event.subscribe(`minus-num${i}`, function (unitPrice, num) {
      aSubtotal[i].innerHTML = unitPrice * num;
    });
    Event.subscribe(`plus-num${i}`, function (unitPrice, num) {
      aSubtotal[i].innerHTML = unitPrice * num;
    });
  }
})();

Aucun commentaire:

Enregistrer un commentaire