123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- // function reducer(state, {type, ШО, СКОКА}){ //объект action деструктуризируется на три переменных
- // if (!state){ //начальная уборка в ларьке:
- // return {
- // пиво: 100,
- // чипсы: 100,
- // сиги: 100
- // }
- // }
- // if (type === 'КУПИТЬ'){ //если тип action - КУПИТЬ, то:
- // return {
- // ...state, //берем все что было из ассортимента
- // [ШО]: state[ШО] - СКОКА //и уменьшаем то, что покупается на количество
- // }
- // }
- // return state //если мы не поняли, что от нас просят в `action` - оставляем все как есть
- // }
- // function createStore(reducer){
- // let callbacks = []
- // let state = reducer(undefined, {});
-
- // return {
- // dispatch(action){
- // const newState = reducer(state, action)
- // if (newState !== state){
- // state = newState
- // for (const cb of callbacks) cb()
- // }
- // },
- // subscribe(callback){
- // callbacks.push(callback)
- // return () => callbacks = callbacks.filter(c => c !== callback)
- // },
- // getState(){
- // return state;
- // }
- // }
- // }
- // const store = createStore(reducer)
- // //запомнит функцию во внутреннем массиве cbs.
- // //она будет запущена при любом успешном dispatch
- // const unsubscribe = store.subscribe(() => console.log(store.getState()))
- function createStore(reducer){
- let state = reducer(undefined, {}) //стартовая инициализация состояния, запуск редьюсера со state === undefined
- let cbs = [] //массив подписчиков
-
- const getState = () => state //функция, возвращающая переменную из замыкания
- const subscribe = cb => (cbs.push(cb), //запоминаем подписчиков в массиве
- () => cbs = cbs.filter(c => c !== cb)) //возвращаем функцию unsubscribe, которая удаляет подписчика из списка
-
- const dispatch = action => {
- const newState = reducer(state, action) //пробуем запустить редьюсер
- if (newState !== state){ //проверяем, смог ли редьюсер обработать action
- state = newState //если смог, то обновляем state
- for (let cb of cbs) cb() //и запускаем подписчиков
- }
- }
-
- return {
- getState, //добавление функции getState в результирующий объект
- dispatch,
- subscribe //добавление subscribe в объект
- }
- }
-
- function reducer(state, {type, ШО, СКОКА, БАБЛО}){ //объект action деструктуризируется на три переменных
- if (!state){ //начальная уборка в ларьке:
- return {
- пиво: {count: 100, price: 30},
- чипсы: {count: 100, price: 25},
- сиги: {count: 100, price: 50},
- касса: 0,
- }
- }
- if (type === 'КУПИТЬ'){ //если тип action - КУПИТЬ, то:
- //проверить на:
- //наличие товара как такового (есть ли ключ в объекте)
- //количество денег в action
- //наличие нужного количества товара.
- //и только при соблюдении этих условий обновлять state.
- if (ШО in state && СКОКА > 0 && БАБЛО/СКОКА >= state[ШО]['price']) {
- // если запрашиваемое количество товара больше имеющегося, то выдавать все, что есть или ничего не выдавать?
- if (state[ШО]['count'] > СКОКА) {
- return {
- ...state, //берем все что было из ассортимента
- [ШО]: {count: state[ШО]['count'] - СКОКА, price: state[ШО]['price']}, //и уменьшаем то, что покупается на количество
- касса: +state.касса + state[ШО]['price']*СКОКА,
- }
- } else {
- return {
- ...state,
- [ШО]: {count: state[ШО]['count'] - state[ШО]['count'], price: state[ШО]['price']},
- касса: +state.касса + state[ШО]['price']*state[ШО]['count'],
- }
- }
-
- } else {
- return state
- }
- }
- return state //если мы не поняли, что от нас просят в `action` - оставляем все как есть
- }
-
- const store = createStore(reducer)
- //надо бы напилить цикл, который в select напихивает ассортимент.
- //возможно, если вы собираетесь выводить (и обновлять) количество,
- //это надо делать где в subscribe, иначе оно не будет обновлять количество
- // for (const [key, value] of Object.entries(store.getState())) {
- // if (typeof value === 'object') {
- // }
- // }
-
- const купи = (ШО, СКОКА, БАБЛО) => ({type: 'КУПИТЬ', ШО, СКОКА, БАБЛО})
-
- buy.onclick = () => {
- //достает выбранный товар и количество из DOM
- // store.dispatch(купи(....,....))
- let a = store.dispatch(купи(goods.value,quantity.value,money.value))
- }
- // quantity.oninput = () => {
- // }
-
- //запомнит функцию во внутреннем массиве cbs.
- //она будет запущена при любом успешном dispatch
- const unsubscribe = store.subscribe(() => console.log(store.getState()))
-
- //setTimeout(unsubscribe, 10000) //отпишемся через 10 секунд, например
-
- //происходит запуск редьюсера, который создает новый state.
- //dispatch запускает всех подписчиков из массива cbs
-
- function smth() {
- const h1 = document.createElement('h1')
- shop.append(h1)
- store.subscribe(() => h1.innerText = 'Касса: ' + store.getState().касса + ' грн')
- h1.innerText = 'Касса: ' + store.getState().касса + ' грн'
- }
-
- function printTable() {
- const table = document.createElement('table')
- shop.append(table)
- // const trTop = document.createElement('tr')
- // table.append(trTop)
- // const thTop = document.createElement('th')
- // thTop.innerText = 'ТОВАР'
- // trTop.append(thTop)
-
- function renderTable() {
- for (const [key, value] of Object.entries(store.getState())) {
- if (typeof value === 'object') {
- const good = document.createElement('option')
- good.innerText = key + ': ' + value.count + ' шт'
- good.value = key
- goods.append(good)
- const tr = document.createElement('tr')
- table.append(tr)
- const th = document.createElement('th')
- th.innerText = key + ':'
- tr.append(th)
- const tdCount = document.createElement('td')
- const tdPrice = document.createElement('td')
- tdCount.innerText = value.count + ' шт'
- tdPrice.innerText = value.price + ' грн/шт'
- tr.append(tdCount)
- tr.append(tdPrice)
- }
- }
- }
- renderTable()
- store.subscribe(() => {
- goods.innerHTML = ""
- table.innerHTML = ""
- renderTable()
- })
- }
- printTable()
- smth()
-
- setTimeout(() => store.dispatch({type: 'КУПИТЬ', ШО: 'пиво', СКОКА: 3, БАБЛО: 100}), 2000)
|