main.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. function createStore(reducer) {
  2. let state = reducer(undefined, {}) //стартовая инициализация состояния, запуск редьюсера со state === undefined
  3. let cbs = [] //массив подписчиков
  4. const getState = () => state //функция, возвращающая переменную из замыкания
  5. const subscribe = cb => (cbs.push(cb), //запоминаем подписчиков в массиве
  6. () => cbs = cbs.filter(c => c !== cb)) //возвращаем функцию unsubscribe, которая удаляет подписчика из списка
  7. const dispatch = action => {
  8. const newState = reducer(state, action) //пробуем запустить редьюсер
  9. if (newState !== state) { //проверяем, смог ли редьюсер обработать action
  10. state = newState //если смог, то обновляем state
  11. for (let cb of cbs) cb() //и запускаем подписчиков
  12. }
  13. }
  14. return {
  15. getState, //добавление функции getState в результирующий объект
  16. dispatch,
  17. subscribe //добавление subscribe в объект
  18. }
  19. }
  20. function reducer(state, { type, ГДЕ, ШО, СКОКА, БАБЛО }) { //объект action деструктуризируется на три переменных
  21. if (!state) { //начальная уборка в ларьке:
  22. return {
  23. бухло: {
  24. пиво: { count: 100, price: 25 },
  25. святая: { count: 100, price: 35 },
  26. ректификаn: { count: 30, price: 50 },
  27. },
  28. загрызнуть: {
  29. камса: { count: 80, price: 15 },
  30. чипсы: { count: 100, price: 20 },
  31. огурчик: { count: 35, price: 5 },
  32. раки: { count: 15, price: 100 },
  33. },
  34. остальное: {
  35. сиги: { count: 100, price: 35 },
  36. 'Даме шоколад': { count: 100, price: 35 },
  37. },
  38. касса: 0,
  39. 'Моя заначка': 1500//при покупках увеличивается
  40. }
  41. }
  42. if (type === 'КУПИТЬ') {
  43. if ((state[ГДЕ][ШО].count - СКОКА) < 0 || (state['Моя заначка'] - БАБЛО) < 0) {
  44. return state
  45. } else {
  46. return {
  47. ...state, //берем все что было из ассортимента
  48. [ГДЕ]: {
  49. ...state[ГДЕ],
  50. [ШО]: {
  51. ...state[ГДЕ][ШО],
  52. count: state[ГДЕ][ШО].count - СКОКА
  53. }
  54. },
  55. касса: state.касса + БАБЛО,
  56. 'Моя заначка': state['Моя заначка'] - БАБЛО
  57. //и уменьшаем то, что покупается на количество
  58. }
  59. }
  60. //если тип action - КУПИТЬ, то:
  61. //проверить на:
  62. //наличие товара как такового (есть ли ключ в объекте)
  63. //количество денег в action
  64. //наличие нужного количества товара.
  65. //и только при соблюдении этих условий обновлять state.
  66. }
  67. return state //если мы не поняли, что от нас просят в `action` - оставляем все как есть
  68. }
  69. const store = createStore(reducer)
  70. const table = document.createElement('table')
  71. let flag = true
  72. for (const key in store.getState()) {
  73. let optgroup = document.createElement('optgroup')
  74. optgroup.label = key
  75. for (const deepkey in store.getState()[key]) {
  76. let option = document.createElement('option')
  77. option.setAttribute('name', key)
  78. option.innerText = deepkey
  79. optgroup.append(option)
  80. createTable(key, deepkey, flag)
  81. flag = false
  82. }
  83. if (key === 'касса') createCasaCash(kassa, key)
  84. else if (key === 'Моя заначка') createCasaCash(myCash, key)
  85. else {
  86. goods.append(optgroup)
  87. flag = true
  88. }
  89. }
  90. const findSelectedOption = (el) => el.options[el.selectedIndex].getAttribute('name')
  91. const купи = (ГДЕ, ШО, СКОКА, БАБЛО) => ({ type: 'КУПИТЬ', ГДЕ, ШО, СКОКА, БАБЛО })
  92. buy.onclick = () => {
  93. store.dispatch(купи(findSelectedOption(goods), goods.value, quantity.value, store.getState()[findSelectedOption(goods)][goods.value].price * quantity.value))
  94. }
  95. const unsubscribe = store.subscribe(() => console.log(store.getState()))
  96. function createTable(key, deepkey, flag) {
  97. table.setAttribute('border', '1')
  98. const tr = document.createElement('tr')
  99. const th = document.createElement('th')
  100. const tdName = document.createElement('td')
  101. const tdCount = document.createElement('td')
  102. const tdPrice = document.createElement('td')
  103. flag ? th.innerText = key : th.innerText = ''
  104. tdName.innerText = deepkey
  105. tdPrice.innerText = `Цена ${store.getState()[key][deepkey].price} грн`
  106. tdCount.innerText = ` ${store.getState()[key][deepkey].count} шт`
  107. store.subscribe(() => tdCount.innerText = store.getState()[key][deepkey].count)
  108. tr.append(th)
  109. tr.append(tdName)
  110. tr.append(tdPrice)
  111. tr.append(tdCount)
  112. table.append(tr)
  113. products.append(table)
  114. }
  115. function createCasaCash(el, key) {
  116. const tableCasa = document.createElement('table')
  117. tableCasa.setAttribute('border', '1')
  118. const tr = document.createElement('tr')
  119. const th = document.createElement('th')
  120. const td = document.createElement('td')
  121. th.innerText = key
  122. td.innerText = store.getState()[key]
  123. store.subscribe(() => td.innerText = store.getState()[key])
  124. tr.append(th)
  125. tr.append(td)
  126. tableCasa.append(tr)
  127. el.append(tableCasa)
  128. }