index.js 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. // function reducer(state, {type, ШО, СКОКА}){ //объект action деструктуризируется на три переменных
  2. // if (!state){ //начальная уборка в ларьке:
  3. // return {
  4. // пиво: 100,
  5. // чипсы: 100,
  6. // сиги: 100
  7. // }
  8. // }
  9. // if (type === 'КУПИТЬ'){ //если тип action - КУПИТЬ, то:
  10. // return {
  11. // ...state, //берем все что было из ассортимента
  12. // [ШО]: state[ШО] - СКОКА //и уменьшаем то, что покупается на количество
  13. // }
  14. // }
  15. // return state //если мы не поняли, что от нас просят в `action` - оставляем все как есть
  16. // }
  17. // function createStore(reducer){
  18. // let callbacks = []
  19. // let state = reducer(undefined, {});
  20. // return {
  21. // dispatch(action){
  22. // const newState = reducer(state, action)
  23. // if (newState !== state){
  24. // state = newState
  25. // for (const cb of callbacks) cb()
  26. // }
  27. // },
  28. // subscribe(callback){
  29. // callbacks.push(callback)
  30. // return () => callbacks = callbacks.filter(c => c !== callback)
  31. // },
  32. // getState(){
  33. // return state;
  34. // }
  35. // }
  36. // }
  37. // const store = createStore(reducer)
  38. // //запомнит функцию во внутреннем массиве cbs.
  39. // //она будет запущена при любом успешном dispatch
  40. // const unsubscribe = store.subscribe(() => console.log(store.getState()))
  41. function createStore(reducer){
  42. let state = reducer(undefined, {}) //стартовая инициализация состояния, запуск редьюсера со state === undefined
  43. let cbs = [] //массив подписчиков
  44. const getState = () => state //функция, возвращающая переменную из замыкания
  45. const subscribe = cb => (cbs.push(cb), //запоминаем подписчиков в массиве
  46. () => cbs = cbs.filter(c => c !== cb)) //возвращаем функцию unsubscribe, которая удаляет подписчика из списка
  47. const dispatch = action => {
  48. const newState = reducer(state, action) //пробуем запустить редьюсер
  49. if (newState !== state){ //проверяем, смог ли редьюсер обработать action
  50. state = newState //если смог, то обновляем state
  51. for (let cb of cbs) cb() //и запускаем подписчиков
  52. }
  53. }
  54. return {
  55. getState, //добавление функции getState в результирующий объект
  56. dispatch,
  57. subscribe //добавление subscribe в объект
  58. }
  59. }
  60. function reducer(state, {type, ШО, СКОКА, БАБЛО}){ //объект action деструктуризируется на три переменных
  61. if (!state){ //начальная уборка в ларьке:
  62. return {
  63. пиво: {count: 100, price: 30},
  64. чипсы: {count: 100, price: 25},
  65. сиги: {count: 100, price: 50},
  66. касса: 0,
  67. }
  68. }
  69. if (type === 'КУПИТЬ'){ //если тип action - КУПИТЬ, то:
  70. //проверить на:
  71. //наличие товара как такового (есть ли ключ в объекте)
  72. //количество денег в action
  73. //наличие нужного количества товара.
  74. //и только при соблюдении этих условий обновлять state.
  75. if (ШО in state && СКОКА > 0 && БАБЛО/СКОКА >= state[ШО]['price']) {
  76. // если запрашиваемое количество товара больше имеющегося, то выдавать все, что есть или ничего не выдавать?
  77. if (state[ШО]['count'] > СКОКА) {
  78. return {
  79. ...state, //берем все что было из ассортимента
  80. [ШО]: {count: state[ШО]['count'] - СКОКА, price: state[ШО]['price']}, //и уменьшаем то, что покупается на количество
  81. касса: +state.касса + state[ШО]['price']*СКОКА,
  82. }
  83. } else {
  84. return {
  85. ...state,
  86. [ШО]: {count: state[ШО]['count'] - state[ШО]['count'], price: state[ШО]['price']},
  87. касса: +state.касса + state[ШО]['price']*state[ШО]['count'],
  88. }
  89. }
  90. } else {
  91. return state
  92. }
  93. }
  94. return state //если мы не поняли, что от нас просят в `action` - оставляем все как есть
  95. }
  96. const store = createStore(reducer)
  97. //надо бы напилить цикл, который в select напихивает ассортимент.
  98. //возможно, если вы собираетесь выводить (и обновлять) количество,
  99. //это надо делать где в subscribe, иначе оно не будет обновлять количество
  100. // for (const [key, value] of Object.entries(store.getState())) {
  101. // if (typeof value === 'object') {
  102. // }
  103. // }
  104. const купи = (ШО, СКОКА, БАБЛО) => ({type: 'КУПИТЬ', ШО, СКОКА, БАБЛО})
  105. buy.onclick = () => {
  106. //достает выбранный товар и количество из DOM
  107. // store.dispatch(купи(....,....))
  108. let a = store.dispatch(купи(goods.value,quantity.value,money.value))
  109. }
  110. // quantity.oninput = () => {
  111. // }
  112. //запомнит функцию во внутреннем массиве cbs.
  113. //она будет запущена при любом успешном dispatch
  114. const unsubscribe = store.subscribe(() => console.log(store.getState()))
  115. //setTimeout(unsubscribe, 10000) //отпишемся через 10 секунд, например
  116. //происходит запуск редьюсера, который создает новый state.
  117. //dispatch запускает всех подписчиков из массива cbs
  118. function smth() {
  119. const h1 = document.createElement('h1')
  120. shop.append(h1)
  121. store.subscribe(() => h1.innerText = 'Касса: ' + store.getState().касса + ' грн')
  122. h1.innerText = 'Касса: ' + store.getState().касса + ' грн'
  123. }
  124. function printTable() {
  125. const table = document.createElement('table')
  126. shop.append(table)
  127. // const trTop = document.createElement('tr')
  128. // table.append(trTop)
  129. // const thTop = document.createElement('th')
  130. // thTop.innerText = 'ТОВАР'
  131. // trTop.append(thTop)
  132. function renderTable() {
  133. for (const [key, value] of Object.entries(store.getState())) {
  134. if (typeof value === 'object') {
  135. const good = document.createElement('option')
  136. good.innerText = key + ': ' + value.count + ' шт'
  137. good.value = key
  138. goods.append(good)
  139. const tr = document.createElement('tr')
  140. table.append(tr)
  141. const th = document.createElement('th')
  142. th.innerText = key + ':'
  143. tr.append(th)
  144. const tdCount = document.createElement('td')
  145. const tdPrice = document.createElement('td')
  146. tdCount.innerText = value.count + ' шт'
  147. tdPrice.innerText = value.price + ' грн/шт'
  148. tr.append(tdCount)
  149. tr.append(tdPrice)
  150. }
  151. }
  152. }
  153. renderTable()
  154. store.subscribe(() => {
  155. goods.innerHTML = ""
  156. table.innerHTML = ""
  157. renderTable()
  158. })
  159. }
  160. printTable()
  161. smth()
  162. setTimeout(() => store.dispatch({type: 'КУПИТЬ', ШО: 'пиво', СКОКА: 3, БАБЛО: 100}), 2000)