Вызов API-вызова для каждого элемента в цикле Jinja2 for - PullRequest
0 голосов
/ 16 февраля 2020

В настоящее время я застрял в личном проекте, где я делаю вызовы Fetch API, чтобы получить аудио sr c для списка html звуковых тегов.

Вызов извлечения запускается нажатием кнопки мыши. Событие на трассе. Хотя, независимо от того, на какую дорожку я нажимаю, извлекает call / play_track / 1 / и добавляет аудиоплеер только к первой дорожке. Любой способ исправить это?

Как вы можете видеть мой индекс. html в основном просто jinja2:

{% extends 'base.html' %}

{% block content %}

    {% for track in tracks %}
        {% include '_post.html' %}
    {% endfor %}

{% endblock content %}

Здесь _post. html с вызовом Fetch: (В настоящее время используется событие onclick для вызова, но переключится на onpageload)

image

А вот код бэкэнда: (Который я почти уверен, если я настрою, я могу избежать Fetch все вместе, но это другая проблема)

@bp.route('/play_track/<track_id>/')
def play_track(track_id):

    track = Track.query.filter_by(id=track_id).first()

    res = requests.get(track.audio)
    if not res.status_code == 200:
        return f'Status code: {res.status_code}'

    json_res = json.loads(res.text)
    mpeg_audio_url = json_res['url']

    msg_dict = {
        'url': mpeg_audio_url
    }

    res = make_response(jsonify({'message': msg_dict}))
    return res

Подводя итог: вызовите не понимая Jinja2 для l oop. Кликаю ли я по треку 1, 10 или 46 и т. Д. c, он вызывает / play_track / 1 / и добавляет аудиотег к первому треку.

Спасибо!

1 Ответ

2 голосов
/ 16 февраля 2020
        function fetchURL(event) {
            tid = event.target;
            track_id = tid.innerHTML;

            fetch(`${window.origin}/play_track/${track_id}`)
                .then((response) => {
                    console.log(response.status);
                    return response.json();
                })
                .then(function(data) {
                    console.log(data.message.url);
                    createAudioPlayer(data, event);
                });
        }

Проблема была в первой строке. Вы не получаете текущую цель события.
Идентификаторы должны быть уникальными, поэтому каждый раз, когда вы oop проходите через дорожку, вы создаете элемент с таким же идентификатором. Измените track-id с id на class .

<p onclick="fetchURL(event)" class="track-id">{{ track.id }}</p>

Кроме того, поскольку вы использовали document.getElementById () it вернет первое вхождение этого идентификатора. По этой причине он постоянно возвращал трек 1.
Другое дело, нет смысла иметь его l oop javascript снова и снова, поскольку новые просто переопределяют старые.

Исправлено createAudioPlayer (), обязательно передайте объект события в него. Я уже сделал это для вас, поэтому просто скопируйте новую функцию fetchURL.

        function createAudioPlayer(data, event) {

            let cardBody = event.target.parentElement;

            let audio = document.createElement('audio');
            audio.controls = true;

            let source = document.createElement('source');
            source.type = "audio/mpeg";
            source.src = data.message.url

            cardBody.append(audio);
            audio.prepend(source);
        };
...