index.js 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  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 state = reducer(undefined, {}) //стартовая инициализация состояния, запуск редьюсера со state === undefined
  19. // let cbs = [] //массив подписчиков
  20. // const getState = () => state //функция, возвращающая переменную из замыкания
  21. // const subscribe = cb => (cbs.push(cb), //запоминаем подписчиков в массиве
  22. // () => cbs = cbs.filter(c => c !== cb)) //возвращаем функцию unsubscribe, которая удаляет подписчика из списка
  23. // const dispatch = action => {
  24. // const newState = reducer(state, action) //пробуем запустить редьюсер
  25. // if (newState !== state){ //проверяем, смог ли редьюсер обработать action
  26. // state = newState //если смог, то обновляем state
  27. // for (let cb of cbs) cb() //и запускаем подписчиков
  28. // }
  29. // }
  30. // return {
  31. // getState, //добавление функции getState в результирующий объект
  32. // dispatch,
  33. // subscribe //добавление subscribe в объект
  34. // }
  35. // }
  36. // const store = createStore(reducer)
  37. // const unsubscribe = store.subscribe(() => console.log(store.getState())) //запомнит функцию во внутреннем массиве cbs
  38. // store.dispatch({type: 'КУПИТЬ', ШО: 'пиво', СКОКА: 3});
  39. // store.dispatch({type: 'КУПИТЬ', ШО: 'сиги', СКОКА: 5});
  40. // store.dispatch({type: 'КУПИТЬ', ШО: 'чипсы', СКОКА: 10});
  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: 40},
  66. касса: {bill: 0}, // при покупках увеличивается
  67. кэш: {money: БАБЛО},
  68. }
  69. }
  70. if (type === 'КУПИТЬ'){ //если тип action - КУПИТЬ, то:
  71. //проверить на:
  72. //наличие товара как такового (есть ли ключ в объекте)
  73. //количество денег в action
  74. //наличие нужного количества товара.
  75. //и только при соблюдении этих условий обновлять state.
  76. return {
  77. ...state, //берем все что было из ассортимента
  78. [ШО]: state[ШО].count > СКОКА ? {count: state[ШО].count - СКОКА, price: state[ШО].price} : 'недостаточно товара', //и уменьшаем то, что покупается на количество
  79. [ШО]: state[ШО].price * СКОКА < БАБЛО ? {count: state[ШО].count - СКОКА, price: state[ШО].price} : {count: state[ШО].count},
  80. ['касса']: state[ШО].price * СКОКА < БАБЛО ? {bill: СКОКА * state[ШО].price} : {bill: state['касса'].bill},
  81. ['кэш']: state[ШО].price * СКОКА < БАБЛО ? {money: БАБЛО - state[ШО].price * СКОКА} : 'нет бабок, чел'
  82. }
  83. }
  84. return state //если мы не поняли, что от нас просят в `action` - оставляем все как есть
  85. }
  86. const store = createStore(reducer);
  87. for(let [key] of Object.entries(store.getState())) {
  88. let option = document.createElement('option');
  89. option.innerText = key;
  90. if (key !== 'касса') {
  91. goods.append(option);
  92. }
  93. }
  94. //надо бы напилить цикл, который в select напихивает ассортимент.
  95. //возможно, если вы собираетесь выводить (и обновлять) количество,
  96. //это надо делать где в subscribe, иначе оно не будет обновлять количество
  97. const купи = (ШО, СКОКА) => ({type: 'КУПИТЬ', ШО, СКОКА})
  98. buy.onclick = () => {
  99. let money = store.getState().кэш.money;
  100. let what = goods.value;
  101. let skoka = quantity.value;
  102. console.log(what, skoka);
  103. store.dispatch({type: 'КУПИТЬ', ШО: what, СКОКА: skoka, БАБЛО: money});
  104. //достает выбранный товар и количество из DOM
  105. //store.dispatch(купи(....,....))
  106. }
  107. //запомнит функцию во внутреннем массиве cbs.
  108. //она будет запущена при любом успешном dispatch
  109. const unsubscribe = store.subscribe(() => console.log(store.getState())) ;
  110. //setTimeout(unsubscribe, 10000) //отпишемся через 10 секунд, например
  111. //происходит запуск редьюсера, который создает новый state.
  112. //dispatch запускает всех подписчиков из массива cbs
  113. // let container = document.getElementById('container');
  114. function smth(){
  115. let container = document.getElementById('container');
  116. store.subscribe(() => {
  117. for (let [key, value] of Object.entries(store.getState())) {
  118. let tovar = document.createElement('h1');
  119. container.append(tovar);
  120. if (value.count) {
  121. tovar.innerText = `${key}: ${value.count}`;
  122. } else {
  123. tovar.innerText = `${key}: ${value}`;
  124. }
  125. if (value.bill) {
  126. tovar.innerText = `${key}: ${value.bill}`;
  127. }
  128. if (value.money) {
  129. tovar.innerText = `${key}: ${value.money}`;
  130. }
  131. }
  132. })
  133. }
  134. smth()
  135. // smth()
  136. setTimeout(() => store.dispatch({type: 'КУПИТЬ', ШО: 'пиво', СКОКА: 5, БАБЛО: 1000}), 500)