js.js 5.0 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, productName, productAmount, summ}){
  21. if (!state){ //начальная уборка в ларьке:
  22. return {
  23. пиво: {
  24. amount: 100,
  25. price: 35,
  26. },
  27. чипсы: {
  28. amount: 100,
  29. price: 28,
  30. },
  31. сиги: {
  32. amount: 100,
  33. price: 90,
  34. },
  35. касса: 0
  36. }
  37. }
  38. if (type === 'Купить' && productAmount <= state[productName].amount && summ >= state[productName].price * productAmount){ //если тип action - КУПИТЬ, то:
  39. return {
  40. ...state, //берем все что было из ассортимента
  41. [productName]: {
  42. amount: state[productName].amount - productAmount,
  43. price: state[productName].price
  44. },
  45. касса: state.касса + state[productName].price * productAmount
  46. //и уменьшаем то, что покупается на количество
  47. }
  48. }
  49. return state //если мы не поняли, что от нас просят в `action` - оставляем все как есть
  50. }
  51. function actionCreator (type, productName, productAmount, summ){
  52. return {
  53. type,
  54. productName,
  55. productAmount,
  56. summ
  57. }
  58. }
  59. let store = createStore(reducer);
  60. myState = store.getState()
  61. const showCase = document.createElement('section')
  62. document.body.append(showCase)
  63. showCase.classList.add('showCase')
  64. const productSelect = document.createElement('select')
  65. document.body.append(productSelect)
  66. const productQuantityOrderTitle = document.createElement('div')
  67. productQuantityOrderTitle.innerText = 'Количество:'
  68. document.body.append(productQuantityOrderTitle)
  69. const productQuantityInput = document.createElement('input')
  70. productQuantityInput.type = 'number'
  71. productQuantityInput.min = '0'
  72. document.body.append(productQuantityInput)
  73. const moneyTitle = document.createElement('div')
  74. moneyTitle.innerText = 'Деньги:'
  75. document.body.append(moneyTitle)
  76. const money = document.createElement('input')
  77. money.type = 'number'
  78. money.min = '0'
  79. document.body.append(money)
  80. const buttonBuy = document.createElement('button')
  81. buttonBuy.value = 'Купить'
  82. buttonBuy.innerText = 'Купить'
  83. document.body.append(buttonBuy)
  84. buttonBuy.onclick = () => {
  85. store.dispatch(actionCreator(buttonBuy.value, productSelect.value, +productQuantityInput.value, +money.value))
  86. }
  87. for (const product in store.getState()){
  88. if (product === 'касса') continue
  89. const productCard = document.createElement('div')
  90. productCard.classList.add('productCard')
  91. const productName = document.createElement('h2')
  92. productName.innerText = product
  93. productName.classList.add('productName')
  94. const productPrice = document.createElement('div')
  95. productPrice.innerText = store.getState()[product].price + ' грн'
  96. productPrice.classList.add('productPrice')
  97. const productAmount = document.createElement('div')
  98. productAmount.innerText = store.getState()[product].amount + ' шт'
  99. productAmount.classList.add('productQuantity')
  100. productCard.append(productName, productAmount, productPrice)
  101. showCase.append(productCard)
  102. const productOption = document.createElement('option')
  103. productOption.value = productOption.innerText = product
  104. productSelect.append(productOption)
  105. const productPriceUnsubscribe = store.subscribe( () => {
  106. productPrice.innerText = store.getState()[product].price + ' грн'
  107. })
  108. const productQuantityUnsubscribe = store.subscribe( () => {
  109. productAmount.innerText = store.getState()[product].amount + ' шт'
  110. } )
  111. }