|
@@ -1,24 +1,169 @@
|
|
|
-htmlTree()
|
|
|
-function htmlTree() {
|
|
|
+ // 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()))
|
|
|
|
|
|
-}
|
|
|
|
|
|
-htmlTree()
|
|
|
-function htmlTree() {
|
|
|
|
|
|
-}
|
|
|
|
|
|
-htmlTree()
|
|
|
-function htmlTree() {
|
|
|
|
|
|
-}
|
|
|
|
|
|
-htmlTree()
|
|
|
-function htmlTree() {
|
|
|
+ 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 {
|
|
|
+ пиво: 100, //{count: 100, price: 30}
|
|
|
+ чипсы: 100,//{count: 100, price: 25}
|
|
|
+ сиги: 100,
|
|
|
+ // касса: 0, при покупках увеличивается
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (type === 'КУПИТЬ'){ //если тип action - КУПИТЬ, то:
|
|
|
+ //проверить на:
|
|
|
+ //наличие товара как такового (есть ли ключ в объекте)
|
|
|
+ //количество денег в action
|
|
|
+ //наличие нужного количества товара.
|
|
|
+ //и только при соблюдении этих условий обновлять state.
|
|
|
+ return {
|
|
|
+ ...state, //берем все что было из ассортимента
|
|
|
+ [ШО]: state[ШО] - СКОКА //и уменьшаем то, что покупается на количество
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return state //если мы не поняли, что от нас просят в `action` - оставляем все как есть
|
|
|
+ }
|
|
|
+
|
|
|
+ const store = createStore(reducer)
|
|
|
+ //надо бы напилить цикл, который в select напихивает ассортимент.
|
|
|
+ //возможно, если вы собираетесь выводить (и обновлять) количество,
|
|
|
+ //это надо делать где в subscribe, иначе оно не будет обновлять количество
|
|
|
+ for (const [key, value] of Object.entries(store.getState())) {
|
|
|
+ const good = document.createElement('option')
|
|
|
+ good.innerText = key
|
|
|
+ good.value = key
|
|
|
+ goods.append(good)
|
|
|
+ }
|
|
|
+
|
|
|
+ const купи = (ШО, СКОКА) => ({type: 'КУПИТЬ', ШО, СКОКА})
|
|
|
+
|
|
|
+ buy.onclick = () => {
|
|
|
+ //достает выбранный товар и количество из DOM
|
|
|
+ // store.dispatch(купи(....,....))
|
|
|
+ let a = store.dispatch(купи(goods.value,quantity.value))
|
|
|
|
|
|
-}
|
|
|
+ }
|
|
|
+
|
|
|
+ //запомнит функцию во внутреннем массиве 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().пиво
|
|
|
+ }
|
|
|
+ smth()
|
|
|
+ // smth()
|
|
|
|
|
|
-htmlTree()
|
|
|
-function htmlTree() {
|
|
|
+ function printTable() {
|
|
|
+ const table = document.createElement('table')
|
|
|
+ shop.append(table)
|
|
|
+
|
|
|
+ let obj = store.getState()
|
|
|
|
|
|
-}
|
|
|
+ for (const [key, value] of Object.entries(store.getState())) {
|
|
|
+ const tr = document.createElement('tr')
|
|
|
+ table.append(tr)
|
|
|
+ const th = document.createElement('th')
|
|
|
+ th.innerText = key
|
|
|
+ tr.append(th)
|
|
|
+ const td = document.createElement('td')
|
|
|
+ td.innerText = value
|
|
|
+ tr.append(td)
|
|
|
+ }
|
|
|
+ store.subscribe(() => {
|
|
|
+ table.innerHTML = ""
|
|
|
+ for (const [key, value] of Object.entries(store.getState())) {
|
|
|
+ const tr = document.createElement('tr')
|
|
|
+ table.append(tr)
|
|
|
+ const th = document.createElement('th')
|
|
|
+ th.innerText = key
|
|
|
+ tr.append(th)
|
|
|
+ const td = document.createElement('td')
|
|
|
+ td.innerText = value
|
|
|
+ tr.append(td)
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ }
|
|
|
+ printTable()
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ setTimeout(() => store.dispatch({type: 'КУПИТЬ', ШО: 'пиво', СКОКА: 3}), 5000)
|