В предыдущем посте продукты были добавлены в базу данных, и эти сохраненные элементы отображались на странице индекса.

В этом посте мы подробно расскажем о тележке для покупок. Есть возможность использовать пакет, который позаботится об этом, но я бы предпочел создать его сам.

Идея состоит в том, чтобы сохранить в сеансе объект с именем «тележка». У объекта будет три свойства;

  • Предметы
  • 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')
}

На этом этот пост подошел к концу. Далее будет страница оформления заказа и создание заказа.

Если у вас есть какие-либо вопросы или проблемы, оставьте комментарий ниже.