123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- 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, productName, productAmount, sum}){
- if (!state){ //начальная уборка в ларьке:
- return {
- пиво: {
- amount: 100,
- price: 35,
- },
- чипсы: {
- amount: 100,
- price: 28,
- },
- сиги: {
- amount: 100,
- price: 90,
- },
- }
- }
- if (type === 'Купить' && productAmount <= state[productName].amount && sum >= state[productName].price * productAmount){ //если тип action - КУПИТЬ, то:
- return {
- ...state,[productName]: {
- amount: state[productName].amount - productAmount,
- price: state[productName].price
- },
- }
- }
- return state //если мы не поняли, что от нас просят в `action` - оставляем все как есть
- }
- function actionCreator (type, productName, productAmount, sum){
- return {
- type,
- productName,
- productAmount,
- sum
- }
- }
- let store = createStore(reducer);
- myState = store.getState()
- const showCase = document.createElement('section')
- document.body.append(showCase)
- showCase.classList.add('showCase')
- const productSelect = document.createElement('select')
- document.body.append(productSelect)
- const productQuantityOrderTitle = document.createElement('div')
- productQuantityOrderTitle.innerText = 'Количество:'
- document.body.append(productQuantityOrderTitle)
- const productQuantityInput = document.createElement('input')
- productQuantityInput.type = 'number'
- productQuantityInput.min = '0'
- document.body.append(productQuantityInput)
- const moneyTitle = document.createElement('div')
- moneyTitle.innerText = 'Деньги:'
- document.body.append(moneyTitle)
- const money = document.createElement('input')
- money.type = 'number'
- money.min = '0'
- document.body.append(money)
- const buttonBuy = document.createElement('button')
- buttonBuy.value = 'Купить'
- buttonBuy.innerText = 'Купить'
- document.body.append(buttonBuy)
- buttonBuy.onclick = () => {
- store.dispatch(actionCreator(buttonBuy.value, productSelect.value, +productQuantityInput.value, +money.value))
- }
- for (const product in store.getState()){
- const productCard = document.createElement('div')
- productCard.classList.add('productCard')
- const productName = document.createElement('h2')
- productName.innerText = product
- productName.classList.add('productName')
- const productPrice = document.createElement('div')
- productPrice.innerText = store.getState()[product].price + ' грн'
- productPrice.classList.add('productPrice')
- const productAmount = document.createElement('div')
- productAmount.innerText = store.getState()[product].amount + ' шт'
- productAmount.classList.add('productQuantity')
- productCard.append(productName, productAmount, productPrice)
- showCase.append(productCard)
- const productOption = document.createElement('option')
- productOption.innerText = product
- productSelect.append(productOption)
- const productAmountChange= store.subscribe( () => {
- productAmount.innerText = store.getState()[product].amount + ' шт'
- })
- }
|