Рубрики
Без рубрики

Колбовая серия Часть 8: Улучшение пользовательского опыта, используя входные чипы и раскрывающееся меню

Внедрение В прошлый раз, в предыдущем доме в нашей серии, мы сосредоточились на значительном улучшении … с меткой Python, WebDev, Flask.

SLOSK SERIES (13 Часть серии)

Вступление

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

Теперь мы расширим эту функциональность, добавив входные чипы и дополнительная отзывчивость к нашей заявке.

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

Это то, что он будет выглядеть:

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

Как связать это все вместе от того, что у нас сейчас

Это интересная особенность, потому что она позволяет для некоторого пространства для архитектуры и проектирования хорошего потока. Есть много способов поступить об этом при использовании разных стеков и/или способы структурирования кода:

  • Используйте EventBus для «моста» компонентов вместе: Guava Guava Guava – это механизм включения связи между кажущимися бесчисленными отключенными компонентами. Существует глобальный объект, экземпляр EventBus, который позволяет классы регистрировать как отправители событий через шину, а приемники должны реализовать определенный тип обратного списка для приема значений, прошедших через шину.

Это эффективный, практичный и еще опасный раствор, поскольку EventBus в основном обходит любые существующие границы, налагаемые текущей структурой кода, и она может выйти из руки очень быстро.

  • Используя стандартную композицию и аналогичные образцы дизайна, такие как наблюдатель. Компоненты являются иерархически организованными, а узоры проектирования делают лучшие из таких иерархий, что позволяет безопасно, предсказуемое связь между компонентами.

  • Мы можем использовать API-адреса для отдыха и сервера, чтобы включить связь между интерфейсом и сервером, который обрабатывает запросы и сохраняет состояние, передаю состояние на фронт через HTML-шаблоны в виде JSON, которые обновляются в качестве ответа на взаимодействие пользователей на интерфейсе.

Последний подход – это тот, который мы возьмем, поскольку мы разрабатываем спокойное веб-приложение, а наш интерфейс использует HTML и JS. Это также очень стандартный подход, который позволяет много экспериментов и возможностей с точки зрения его архитектуры. Вот диаграмма нашего потока:

Давайте пройдемся, поэтому у нас есть лучшая идея текущего потока кода в данный момент:

Все начинается в интернет-конце, где пользователь в строке поиска для ингредиентов, чтобы получить рецепты.

Затем мы связываем функцию обратного вызова на кликере, которая будет нести ответственность за выполнение запроса AJAX на наш сервер Flask, чтобы опубликовать данные наших JSON на определенную конечную точку. Там мы будем хранить ингредиент, который пользователь введен в качестве ввода в двух таблицах в нашей базе данных: Searchsuggestion и IngredientChip Столы, которые будут нести ответственность за представление лучших пяти самых последних поисков всем пользователям и для хранения предложений поиска, набранных пользователем, чтобы оба придумать поиск, и создать компонент UI. С результатами, хранящимися в базе данных, мы отправляем успешный ответ на интерфейс, чтобы вызвать OnSuccess Обратный вызов запроса AJAX, который выполняется после успешного ответа, получено асинхронно.

Там мы используем jQuery, чтобы заставить щелчок нашей кнопке поиска, которая затем публикует содержимое, которое находится в форме на нашу главную конечную точку, это было вождение нашего поиска ранее. Теперь такая функциональность исчезла, и только раскрывающийся список водит поиск, через AJAX Shump сначала сначала сохранить введенный ингредиент в базе данных, и, в ответ, принудительно нажав кнопку на кнопке поиска, которая использует ранее сохраненную информацию Чтобы построить контент JSON, который будет включать шаблоны Jinja.

После того, как Jsons готовы и построены, мы используем Spoonacular API для извлечения рецептов, которые содержат ингредиенты в базе данных, создают ответ JSON, содержащие все рецепты, а также Render_template Метод будет гарантировать, что шаблоны правильно построены, и потом сделаны.

Одиночная ответственность принцип

Принцип одной ответственности заявляет, что класс, метод или функция должны делать только одну вещь и только одну вещь.

Этот принцип также может быть применен к нашему текущему дизайну API.

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

Это видно тем, что наша главная конечная точка теперь выглядит так:

@app.route('/', methods=['GET', 'POST'])
def get_recipe():
    ingredients_searched = []
    chip_ingredients = []
    suggestions_as_json = {"searches": ingredients_searched}
    chip_ingredients_as_json = {"chipIngredients": chip_ingredients}
    if request.method == 'POST':
        search_suggestions = select(prod for prod in SearchSuggestion).order_by(lambda prod: desc(prod.id))[:5]
        for entry in search_suggestions:
            ingredients_searched.append(entry.ingredient)
        suggestions_as_json = {"searches": ingredients_searched}

        ing_suggestions = select(prod for prod in IngredientChip)
        for entry in ing_suggestions:
            chip_ingredients.append(entry)
        chip_ingredients_as_json = {"chipIngredients": chip_ingredients}

        ingredients = ",".join(map(lambda db_entry: db_entry.ingredient, chip_ingredients))
        content = requests.get(
            +
            convert_input(ingredients) +
            + API_KEY)
        json_response = json.loads(content.text)
        print json_response
        return render_template("recipes_list.html", ans=json_response, searchHistory=suggestions_as_json,
                               chipIngredients=chip_ingredients_as_json) if json_response != [] else render_template(
            "recipes_list.html", ans="", searchHistory=suggestions_as_json, chipIngredients=chip_ingredients_as_json)
    else:
        delete(ingredient for ingredient in IngredientChip)
        return render_template("recipes_list.html", searchHistory=suggestions_as_json,
                               chipIngredients=chip_ingredients_as_json)

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

Эта конечная точка теперь использует значения, вычисляемые через отдельный Конечная точка, чтобы получить рецепты, которые мы хотим.

Это приводит к увеличению как функциональность, так и конечной точки зрения:

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

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

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

Эта последняя точка иллюстрирует жизненно важную роль в развитии:

Со временем функциональные возможности изменится, адаптируются и растут, будут введены регрессии. Хитрость заключается в том, чтобы иметь в виду конечную цель и определенные архитектурные узоры, которые позволяют вам получить туда, где вы хотите быть.

Добавьте фишки на пользовательский интерфейс

Чтобы добавить фишки в пользовательский интерфейс, мы сначала определим наш компонент заполнителя в шаблоне HTML Jinja:

{% for entry in chipIngredients['chipIngredients'] %} {% endfor %}

Это итерации по списку Чипгеридиенты У нас есть и делает кнопку из каждой записи, на которую мы связываем DelteEntry функция , это делает запрос на удаление через AJAX для удаления текущей записи из БД:

function deleteEntry(id){
    $.ajax({
        type: 'DELETE',
        url: '/deleteIngredient/' + id,
        success: function () {
            $('#searchBtn').trigger("click");
        },
        fail: function () {
            console.log("Error in deleting")
        }
    });
}

На успех мы вызываем новый поиск, который затем будет выполнен только с доступными в настоящее время ингредиенты, как объяснено на диаграмме выше.

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

Наконец, мы добавляем CSS в компонент чипа:

#chipButton {
    display: inline-block;
    padding: 0 10px;
    height: 25px;
    font-size: 14px;
    line-height: 18px;
    border-radius: 25px;
    background: #e8a444;
    color: white;
}

И мы закончили!

Заключение

Очень важно осознать, что иногда некоторые особенности могут быть достижены только благодаря сознательной очистке кода и рефакторинга, которые будут заложить основы, которые позволят вам разработать хорошую архитектуру, которая может оба:

  • Быть достиженным с текущим состоянием кодовой базы;

  • Получите ваше приложение, где вы хотите, чтобы он был, в то же время, в то же время, позволяющий для дальнейших уточнений и улучшений;

Последний пункт, возможно, очень трудно добиться без какой-то тяжелой архитектурной работы, которая должна иметь возможность «предсказать будущее», то есть код должен быть достаточно гибким, чтобы быть достаточно расширенным и многоразовым, если применимо.

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

Оставайтесь настроиться на большее, и, спасибо за чтение!

SLOSK SERIES (13 Часть серии)

Оригинал: “https://dev.to/brunooliveira/flask-series-part-8-improving-user-experience-by-using-input-chips-and-a-dropdown-menu-3a1m”