Как я могу надлежащим образом обслуживать файл stati c js, интегрированный с flask? - PullRequest
1 голос
/ 09 мая 2020

В настоящее время я прохожу веб-программирование с Python и Javascript через EDX. В частности, я использую Socket.IO. Я столкнулся с ошибкой, которую я не совсем уверен, как исправить, и мне было интересно, может ли кто-нибудь помочь. Это исходный код самого курса.

Структура файла:

-venv
     -static
            -index.js
     -templates
            -index.html
     -application.py

Вот application.py:

import os

from flask import Flask, jsonify, render_template, request
from flask_socketio import SocketIO, emit

app = Flask(__name__)
app.config["SECRET_KEY"] = os.getenv("SECRET_KEY")
socketio = SocketIO(app)

votes = {"yes": 0, "no": 0, "maybe": 0}


@app.route("/")
def index():
    return render_template("index.html", votes=votes)


@socketio.on("submit vote")
def vote(data):
    selection = data["selection"]
    votes[selection] += 1
    emit("vote totals", votes, broadcast=True)

Вот index. js :

document.addEventListener('DOMContentLoaded', () => {

    // Connect to websocket
    var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port);

    // When connected, configure buttons
    socket.on('connect', () => {

        // Each button should emit a "submit vote" event
        document.querySelectorAll('button').forEach(button => {
            button.onclick = () => {
                const selection = button.dataset.vote;
                socket.emit('submit vote', {'selection': selection});
            };
        });
    });

    // When a new vote is announced, add to the unordered list
    socket.on('vote totals', data => {
        document.querySelector('#yes').innerHTML = data.yes;
        document.querySelector('#no').innerHTML = data.no;
        document.querySelector('#maybe').innerHTML = data.maybe;
    });
});

Вот индекс. html:

<html>

<head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js">
    </script>
    <script type="text/javascript" src="{{url_for('static', filename='index.js')}}"></script>
    <title>Vote</title>
</head>

<body>
    <div>Yes Votes: <span id="yes">{{ votes["yes"] }}</span></div>
    <div>No Votes: <span id="no">{{ votes["no"] }}</span></div>
    <div>Maybe Votes: <span id="maybe">{{ votes["maybe"] }}<span></div>
        <hr>
        <button data-vote="yes">Yes</button>
        <button data-vote="no">No</button>
        <button data-vote="maybe">Maybe</button>      
    </body>

</html>

Проблема, с которой я столкнулся, заключается в том, что приложение, как оно есть, не работает. Это будет работать, только если я вставлю js прямо в файл HTML. По какой-то причине использование его как файла stati c не работает. Когда я пытаюсь использовать его как файл stati c, у меня появляется консольная ошибка «Uncaught TypeError: Cannot set property 'onclick' of null». Я предполагаю, что проблема в том, что содержимое не загружается к моменту запуска сценария, однако перемещение сценария на странице html, похоже, ничего не дает. Есть ли предложения?

Спасибо.

Ответы [ 2 ]

1 голос
/ 09 мая 2020

Решение этой проблемы заключалось в том, чтобы вставить index.js в папку js в папке static и переместить скрипт в нижнюю часть тела.

Final HTML code:

<!DOCTYPE html>
<html>

<head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js">
    </script>
    <title>Vote</title>
</head>

<body>
    <div>Yes Votes: <span id="yes">{{ votes["yes"] }}</span></div>
    <div>No Votes: <span id="no">{{ votes["no"] }}</span></div>
    <div>Maybe Votes: <span id="maybe">{{ votes["maybe"] }}<span></div>
        <hr>
        <button data-vote="yes" id="yesvote">Yes</button>
        <button data-vote="no" id="novote">No</button>
        <button data-vote="maybe" id="maybevote">Maybe</button>  
        <script type="text/javascript" src="{{url_for('static', filename='js/index.js')}}"></script>    
    </body>

</html>
0 голосов
/ 09 мая 2020

Во-первых, вам нужно поместить файлы javascript в папку static/js. Кроме того, причина, по которой вы получаете cannot set property of undefined, - это проблема в вашем коде HTML, где вы устанавливаете id равным количеству голосов. Вы должны установить идентификатор для тегов кнопок. Вот решение:

<html>

<head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js">
    </script>
    <script type="text/javascript" src="{{url_for('static', filename='index.js')}}"></script>
    <title>Vote</title>
</head>

<body>
    <div>Yes Votes: <span>{{ votes["yes"] }}</span></div>
    <div>No Votes: <span>{{ votes["no"] }}</span></div>
    <div>Maybe Votes: <span>{{ votes["maybe"] }}<span></div>
        <hr>
        <button data-vote="yes" id="yes">Yes</button>
        <button data-vote="no" id="no">No</button>
        <button data-vote="maybe" id="yes">Maybe</button>      
    </body>

</html>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...