Недавно я объединился с двумя другими моими товарищами по группе, чтобы завершить наш первый проект во время нашего пребывания в программе разработки программного обеспечения FlatIron. Наш проект Refrigersaver был разработан как инструмент для сокращения пищевых отходов. Если вы когда-нибудь сталкивались с ситуацией, когда в вашем холодильнике испортился какой-либо ингредиент, но вы не знаете, что с ним приготовить, Refrigersaver может предоставить вам рецепты на основе запрашиваемого вами ингредиента. С самого начала мы знали, что хотим решить сложную задачу реализации операций CRUD в нашем одностраничном приложении.

Для новичков или незнакомых с компьютерным программированием CRUD означает создание, чтение, обновление и удаление. Это четыре основные функции, которые мы хотели, чтобы наша программа выполняла с упорством. При работе с операциями CRUD вы, как и мы, можете столкнуться с некоторыми проблемами, связанными с областью действия.

Изучив множество бесплатных API, имеющихся в нашем распоряжении, мы остановились на API MealDB (API MDB) для создания случайных рецептов в зависимости от ингредиентов, введенных пользователем сайта. Для этого мы использовали запрос на получение информации из API MDB, который заполнял список блюд в верхней части страницы для выбора пользователями. Затем пользователи могли щелкнуть любое из перечисленных блюд, чтобы отобразить соответствующее изображение блюда, ингредиенты и инструкции по приготовлению.

Если пользователь решит, что ему действительно понравилось блюдо, он может добавить его в свой список избранного. Чтобы сохранить избранные рецепты, мы использовали пакет в npm (менеджер пакетов узла) под названием JSON Server, который эмулирует полный RESTful API на локальном сервере. Когда пользователь добавляет блюдо в свой список избранного, мы отправляем запрос на получение POST, чтобы отправить объект новое блюдо, содержащий содержимое любимого блюда, а также новый объект с ключом комментарии и пустым значением. который мы позже будем использовать, чтобы добавлять комментарии к нашим блюдам. Мы создали этот объект новая еда, используя оператор распространения для объединения двух объектов.

Мы хотели, чтобы пользователи могли оставлять себе заметки о любимых рецептах, чтобы вернуться к ним позже, если рецепту нужно немного больше соли или немного меньше перца! Наш первоначальный подход состоял в том, чтобы создать запрос на выборку «PATCH», чтобы изменить значение нашего ключа «комментарии» для данной еды (искомой по идентификатору в нашей локальной базе данных).

Однако я быстро понял, что у нас была небольшая проблема с масштабом. Из-за того, что я изначально решил поместить наш прослушиватель событий «отправить» для нашей формы комментариев, каждое блюдо, выбранное из списка избранного, будет помещено в наш запрос на выборку PATCH, таким образом обновляя несколько блюд одновременно с комментарием, не предназначенным для них. Чтобы исправить эту проблему, в наш код были внесены два изменения с использованием некоторых трюков, связанных с областью действия!

При первоначальном отображении списка избранного функция .forEach() выполняет итерацию по каждому индексу FavoriteMealArray и отображает изображение и заголовок на основе информации, найденной в каждом объекте еды с заданным индексом. Когда функции renderFavorites() передается объект еды, она прикрепляет прослушиватель событий щелчка, чтобы отобразить детали еды в DOM.

Из-за того, что наш прослушиватель событий отправки находится в другой функции, которая повторяется, мы создали прослушиватели событий отправки, каждый из которых привязан к любимому блюду. Поэтому, когда несколько любимых блюд были нажаты перед «отправить», все эти прослушиватели событий ожидали отправки из формы комментариев. Несмотря на то, что в данный момент была отображена одна форма комментария, функция обратного вызова addComment() уже была загружена в заданную область (функция renderFavoriteDetails еды) с едой, по которой щелкнули.

Размещение прослушивателя событий отправки внутри функции renderFavoriteDetails дало ему область действия на функциональном уровне. Согласно функции renderFavoriteDetails, блюдо, переданное нашему обработчику события «отправить», будет тем блюдом, на которое был нажат щелчок. Таким образом, проблема общей картины заключалась в том, что несколько событий «отправить» прослушивались в одной и той же форме в каждом любимом блюде, потому что это заставляло бы функции addComment вызываться одновременно при «отправке».

Я переместил этот обработчик событий, прикрепленный к нашей форме комментария, в положение, обеспечивающее ему глобальную область действия, удалив его из цикла .forEach(), который отображал список избранного. Это устранило проблему, которая была создана из нескольких прослушивателей событий отправки, существующих одновременно, которые прослушивали «отправить» в форме комментариев. Однако теперь у меня была другая проблема на моих руках.

Прослушиватель событий «addComment» должен был принять объект еды, чтобы выбрать правильный рецепт в нашей базе данных и обновить значение его ключа «комментарий». Я объявил новую глобальную переменную с помощью «let», что позволило переназначить ее вниз по цепочке областей видимости, и назвал ее globalMeal. В функции, которая будет отображать наши любимые детали при нажатии на любимое блюдо и, таким образом, позволит нам добавить комментарий, я установил значение globalMeal как отображаемое блюдо. Глобальный охват снова спасает положение!

Теперь каждый раз, когда щелкали по любимому блюду и отображались подробности, значение globalMeal перезаписывалось. Таким образом, всякий раз, когда комментарий добавляется к еде, globalMeal имеет значение одного блюда, на которое вы хотите добавить комментарий!

Наш список фаворитов быстро рос, когда мы тестировали наше приложение, и мы быстро поняли, что нам нужно реализовать последнюю операцию CRUD, удаление! К каждому из наших фаворитов была добавлена ​​кнопка удаления, которая указывала бы на его parentNode, контейнер div, содержащий название и фотографию блюд. В функции обратного вызова этой кнопки удаления мы сделали запрос на выборку DELETE на наш локальный сервер, который нацелил бы еду по идентификатору и удалил ее из нашей базы данных.

Большой вынос? Настройка функций вашего приложения с учетом области действия с самого начала может избавить вас от головной боли в будущем.

Проверьте мой профиль на github по следующей ссылке: https://github.com/garrettstrohm

Оформить заказ на мой проект Refrigersaver можно по следующей ссылке на github: https://github.com/danolef/Phase-1-Group-Project