Procházet zdrojové kódy

+js/12(redux)/index.html

ilya_shyian před 3 roky
rodič
revize
be574e697a
1 změnil soubory, kde provedl 118 přidání a 0 odebrání
  1. 118 0
      js/12(redux)/index.html

+ 118 - 0
js/12(redux)/index.html

@@ -0,0 +1,118 @@
+<!DOCTYPE html>
+<html lang="en">
+    <head>
+        <meta charset="UTF-8" />
+        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+        <title>Document</title>
+    </head>
+    <body>
+        <select name="" id="selectItems"></select>
+        <input type="number" name="" id="inputAmountToBuy" />
+        <button type="button" id="buyBtn">Buy</button>
+
+        <div id="container">
+            <table id="stateTable" border="1"></table>
+        </div>
+
+        <script>
+            const store = createStore(reducer);
+
+            for ([key, value] of Object.entries(store.getState()["продукты"])) {
+                let option = document.createElement("option");
+                option.innerText = key;
+                option.value = key;
+                selectItems.append(option);
+            }
+
+            const buyItem = (amount, item) => ({
+                type: "КУПИТЬ",
+                ШО: item,
+                СКОКА: amount,
+            });
+
+            buyBtn.onclick = () => {
+                let amount = inputAmountToBuy.value;
+                let item = selectItems.value;
+                store.dispatch(buyItem(amount, item));
+
+                console.log(amount);
+            };
+
+            const updateTable = () => {
+                let str = "<tr><th>Название</th><th>Количество</th><th>Цена</th></tr>";
+                let state = store.getState();
+                for ([key, value] of Object.entries(state["продукты"])) {
+                    str += `<tr><th>${key}</th><td>${value.amount}</td><td>${value.cost}</td></tr>`;
+                }
+                str += `<th>касса</th><td colspan = "2">${state["касса"]}</td></tr>`;
+                stateTable.innerHTML = str;
+            };
+
+            store.subscribe(updateTable);
+            store.subscribe(() => console.log(store.getState()));
+            updateTable();
+
+            function reducer(state, { type, ШО, СКОКА }) {
+                //объект action деструктуризируется на три переменных
+                if (!state) {
+                    //начальная уборка в ларьке:
+                    return {
+                        продукты: {
+                            пиво: { amount: 100, cost: 33 },
+                            чипсы: { amount: 100, cost: 13 },
+                            сиги: { amount: 100, cost: 43 },
+                        },
+
+                        касса: 0,
+                    };
+                }
+                if (type.toUpperCase() === "КУПИТЬ") {
+                    let products = state["продукты"];
+                    if (СКОКА <= 0 || СКОКА > state["продукты"][ШО]["amount"]) {
+                        return state;
+                    }
+
+                    return {
+                        ...state, //берем все что было из ассортимента
+                        ["продукты"]: {
+                            ...products,
+                            [ШО]: {
+                                ...products[ШО],
+                                amount: products[ШО]["amount"] - СКОКА,
+                            },
+                        },
+                        касса: +state["касса"] + +products[ШО]["cost"] * +СКОКА, //и уменьшаем то, что покупается на количество
+                    };
+                }
+                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 в объект
+                };
+            }
+        </script>
+    </body>
+</html>