В предыдущем посте продукты были добавлены в базу данных, и эти сохраненные элементы отображались на странице индекса.
В этом посте мы подробно расскажем о тележке для покупок. Есть возможность использовать пакет, который позаботится об этом, но я бы предпочел создать его сам.
Идея состоит в том, чтобы сохранить в сеансе объект с именем «тележка». У объекта будет три свойства;
- Предметы
- totalQty
- Итоговая цена
Свойство «items» - это объект, который содержит другие вложенные в него объекты. Эти вложенные объекты являются продуктами, использующими их «идентификатор продукта» в качестве ключей объекта. Каждый товар имеет два свойства - «количество» и «продукт». Количество представляет собой номер этого конкретного элемента, который пользователь кладет в корзину, а свойство продукта - это сам продукт, который будет извлечен из базы данных.
Ниже представлен образец конструкции тележки.
Настройка маршрута «Получить»
Первое, что нужно сделать, это добавить ссылку, которая соединяется с логикой, которая обрабатывает добавление товара в корзину, в атрибуте href кнопки «добавить в корзину».
На снимке выше я установил ссылку, чтобы принять параметр, которым является идентификатор продукта. Далее необходимо создать маршрут для захвата этой ссылки.
Посмотрите, как я проинструктировал паруса принимать параметр «id» в маршруте добавления в корзину. Этот маршрут подключается к действию «добавить» в «CartController».
Контроллер тележки
Контроллер тележки обрабатывает все, что связано с логикой тележки. Он будет иметь следующие действия - добавить, обновить и удалить. Первое, что нужно сделать здесь, это создать контроллер тележки с помощью генератора парусов ;
sails generate controller cart
В CartController.js, находящемся в каталоге «/ api / controllers», мы создадим такой метод «добавления»;
На приведенном выше снимке вы заметите, что я использовал здесь помощников. В Sails рекомендуется использовать помощники для извлечения повторяющегося кода в отдельный файл, а затем повторного использования этого кода в различных действиях, настраиваемых ответах, сценариях командной строки, модульных тестах или даже в других помощниках. Также это помогает поддерживать чистый и читаемый код.
Блок if
в действии «добавить» проверяет, есть ли в сеансе идентификатор корзины. Если есть, он обновляет корзину с помощью помощника updateCart. Если нет, он создает идентификатор корзины в сеансе и добавляет в него товар с помощью помощника addToCart. В обоих случаях обновленная корзина запускается.
addToCart Helper
«Входы» определяют значения, необходимые для работы функции «fn». В этом случае для работы функции «fn» необходимы «productId» и «productQty».
На снимке выше помощник сначала ищет продукт с помощью метода find()
и сохраняет его в переменной под названием «product».
Затем настраивается базовая структура тележки, и товар, являющийся первым товаром, помещается в объект «items».
В контроллере тележки возвращенная тележка затем помещается в сеанс.
updateCart Helper
Этот помощник принимает req
, который будет передан от CartController, поскольку все, что потребуется для работы этого помощника, уже находится в объекте запроса.
Первый блок if
проверяет, существует ли параметр с именем «qty», и если «qty» больше или равно 1. Если это правда, он устанавливает для переменной «qty» значение параметра «qty» на объект запроса. Если проверка ложна, затем проверяется наличие каких-либо свойств у объекта req.body
. Если есть, он устанавливает для переменной «qty» значение свойства «количество» объекта req.body
. Если обе проверки завершились неудачно, переменная «qty» по умолчанию будет равна 1.
Обратите внимание, что блок if
проверяет как объекты req.param
, так и req.body
, чтобы иметь возможность установить переменную «qty». По сути, значение количества в объектеreq.body
будет использоваться для обновления товара, уже находящегося в корзине, а значение количества в объекте req.param
будет использоваться для добавления новых товаров в корзину.
Последний блок if заботится об обновлении корзины. Обратите внимание, что я добавил строку «элемент» к «идентификатору продукта». Это было добавлено, чтобы сделать ключ объекта доступным для чтения, поскольку идентификатор продукта может иметь целое число в качестве первого символа, что приведет к ошибке при выполнении кода.
Этот блок if
проверяет, находится ли товар уже в текущей корзине. Если это так, он обновляет количество, общее количество и общую цену. Если проверка не удалась, это означает, что это новый продукт, который добавляется в корзину, поэтому он просто помещает его в объект items
с идентификатором продукта в качестве ключа, а затем обновляет общее количество и общую цену соответственно.
Если товар уже находится в корзине, он обновляет количество товара, заменяя его новым значением в «товарах». totalQty и totalPrice обновляются путем удаления значения начальной цены и количества из соответствующих итоговых значений, а затем вычисляется общая цена товара, который только что добавлен в корзину, и добавляет его к существующей общей цене. Количество товара также добавляется к существующему «totalQty» после того, как начальное количество товара было вычтено.
Создание страницы корзины
Во-первых, нужно настроить маршрут и действие для этой страницы. В файле routes.js
в каталоге config
мы добавляем такой маршрут;
'get /cart': 'PageController.showCartPage'
В PageController мы добавляем действие showCartPage
, которое извлекает корзину в сеансе и отправляет ее на страницу корзины.
showCartPage: function(req, res) { var cart = req.session.cart if (cart != undefined) { var items = cart.items } else { var items = 0 } return res.view('pages/cart', {items: items}) }
И в папке страниц мы добавляем представление с именем cart.ejs
. В файле есть блок if
, который проверяет, есть ли в сеансе тележка. Если это не удается, он сообщает пользователю, что в корзине нет товаров, в противном случае он отображает товар в корзине.
<% if (items == 0 || items.totalQty == 0 ) { -%> <h3>Sorry, no items in your cart</h3> <% } else { -%> <table class="table table-borderless"> <thead> <tr> <th>Item</th> <th>Quantity</th> <th>Price</th> <th></th> </tr> </thead> <tbody> <% Object.keys(items).forEach( function(item) { %> <tr> <td> <%= items[item].product.name %> </td> <td> <form action="/update-cart-item" method="post"> <input type="hidden" name="_csrf" value="<%= _csrf %>"> <select name="quantity"> <option value="<%= items[item].qty %>" selected><%= items[item].qty %></option> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> </select> <input type="hidden" name="productId" value="<%= items[item].product.id %>"> <button type="submit" class="btn">Update</button> </form> </td> <td> <%= items[item].product.price * items[item].qty%> </td> <td><a href="/remove-item/<%= items[item].product.id %>">x</a></td> </tr> <% }) %> </tbody> </table> <% } -%>
Обновление элемента корзины отправляется по тому же маршруту, который был создан в предыдущей публикации для обновления продукта. Никаких новых маршрутов или действий создано не было.
Удаление элемента
У каждого товара на странице корзины есть такая ссылка для удаления;
<td><a href="/remove-item/<%= items[item].product.id %>">x</a></td>
Маршрут;
'get /remove-item/:id': 'CartController.remove'
Действие в CartController;
remove: function(req, res) { var cart= req.session.cart var id = 'item'+req.param('id') //update total qty cart.totalQty = cart.totalQty - cart.items[id].qty //update total price cart.totalPrice = cart.totalQty - cart.items[id].qty * cart.items[id].product.price //delete the item delete cart.items[id] return res.redirect('back') }
На этом этот пост подошел к концу. Далее будет страница оформления заказа и создание заказа.
Если у вас есть какие-либо вопросы или проблемы, оставьте комментарий ниже.