123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- // function reducer(state, {type, ШО, СКОКА}){ //объект action деструктуризируется на три переменных
- // if (!state){ //начальная уборка в ларьке:
- // return {
- // пиво: 100,
- // чипсы: 100,
- // сиги: 100
- // }
- // }
- // if (type === 'КУПИТЬ'){ //если тип action - КУПИТЬ, то:
- // return {
- // ...state, //берем все что было из ассортимента
- // [ШО]: state[ШО] - СКОКА //и уменьшаем то, что покупается на количество
- // }
- // }
- // return state //если мы не поняли, что от нас просят в `action` - оставляем все как есть
- // }
- // 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 в объект
- // }
- // }
- // const store = createStore(reducer)
- // const unsubscribe = store.subscribe(() => console.log(store.getState())) //запомнит функцию во внутреннем массиве cbs
- // store.dispatch({type: 'КУПИТЬ', ШО: 'пиво', СКОКА: 3});
- // store.dispatch({type: 'КУПИТЬ', ШО: 'сиги', СКОКА: 5});
- // store.dispatch({type: 'КУПИТЬ', ШО: 'чипсы', СКОКА: 10});
- 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: 40},
- касса: {bill: 0}, // при покупках увеличивается
- кэш: {money: БАБЛО},
- }
- }
- if (type === 'КУПИТЬ'){ //если тип action - КУПИТЬ, то:
- //проверить на:
- //наличие товара как такового (есть ли ключ в объекте)
- //количество денег в action
- //наличие нужного количества товара.
- //и только при соблюдении этих условий обновлять state.
- return {
- ...state, //берем все что было из ассортимента
- [ШО]: state[ШО].count > СКОКА ? {count: state[ШО].count - СКОКА, price: state[ШО].price} : 'недостаточно товара', //и уменьшаем то, что покупается на количество
- [ШО]: state[ШО].price * СКОКА < БАБЛО ? {count: state[ШО].count - СКОКА, price: state[ШО].price} : {count: state[ШО].count},
- ['касса']: state[ШО].price * СКОКА < БАБЛО ? {bill: СКОКА * state[ШО].price} : {bill: state['касса'].bill},
- ['кэш']: state[ШО].price * СКОКА < БАБЛО ? {money: БАБЛО - state[ШО].price * СКОКА} : 'нет бабок, чел'
- }
- }
- return state //если мы не поняли, что от нас просят в `action` - оставляем все как есть
- }
- const store = createStore(reducer);
- for(let [key] of Object.entries(store.getState())) {
- let option = document.createElement('option');
- option.innerText = key;
- if (key !== 'касса') {
- goods.append(option);
- }
- }
- //надо бы напилить цикл, который в select напихивает ассортимент.
- //возможно, если вы собираетесь выводить (и обновлять) количество,
- //это надо делать где в subscribe, иначе оно не будет обновлять количество
- const купи = (ШО, СКОКА) => ({type: 'КУПИТЬ', ШО, СКОКА})
- buy.onclick = () => {
- let money = store.getState().кэш.money;
- let what = goods.value;
- let skoka = quantity.value;
- console.log(what, skoka);
- store.dispatch({type: 'КУПИТЬ', ШО: what, СКОКА: skoka, БАБЛО: money});
- //достает выбранный товар и количество из DOM
- //store.dispatch(купи(....,....))
- }
- //запомнит функцию во внутреннем массиве cbs.
- //она будет запущена при любом успешном dispatch
- const unsubscribe = store.subscribe(() => console.log(store.getState())) ;
- //setTimeout(unsubscribe, 10000) //отпишемся через 10 секунд, например
- //происходит запуск редьюсера, который создает новый state.
- //dispatch запускает всех подписчиков из массива cbs
- // let container = document.getElementById('container');
- function smth(){
- let container = document.getElementById('container');
- store.subscribe(() => {
- for (let [key, value] of Object.entries(store.getState())) {
- let tovar = document.createElement('h1');
- container.append(tovar);
- if (value.count) {
- tovar.innerText = `${key}: ${value.count}`;
- } else {
- tovar.innerText = `${key}: ${value}`;
- }
- if (value.bill) {
- tovar.innerText = `${key}: ${value.bill}`;
- }
- if (value.money) {
- tovar.innerText = `${key}: ${value.money}`;
- }
- }
- })
- }
- smth()
- // smth()
- setTimeout(() => store.dispatch({type: 'КУПИТЬ', ШО: 'пиво', СКОКА: 5, БАБЛО: 1000}), 500)
|