Как передать список из Python, Jinja2 на JavaScript
Я новичок в JavaScript, и сейчас я имею дело с проблемой. Скажем, у меня есть переменная Python:
listOfItems= ['1','2','3','4','5']
и я передаю его Jinja путем рендеринга HTML, и у меня также есть функция в JavaScript под названием somefunction(variable)
. Я пытаюсь передать каждый элемент "listOfItems". Я пробовал что-то вроде этого:
{% for item in listOfItems %}<br>
<span onclick="somefunction({{item}})">{{item}}</span><br>
{% endfor %}
Можно ли передать список из Python на JavaScript или я должен передать каждый элемент из списка один за другим в цикле? Как я могу это сделать?
Ответы
Ответ 1
Чтобы передать некоторые данные контекста в javascript-код, вы должны сериализовать его так, чтобы он был "понят" javascript (а именно JSON). Вы также должны пометить его как безопасное с помощью фильтра safe
Jinja, чтобы ваши данные не были htmlescaped.
Вы можете добиться этого, сделав что-то вроде этого:
Вид
import json
@app.route('/')
def my_view():
data = [1, 'foo']
return render_template('index.html', data=json.dumps(data))
Шаблон
<script type="text/javascript">
function test_func(data) {
console.log(data);
}
test_func({{ data|safe }})
</script>
Изменить - точный ответ
Итак, чтобы добиться именно того, что вы хотите (перебирайте список элементов и передавайте их в функцию javascript), вам нужно будет сериализовать каждый элемент в вашем списке отдельно. Тогда ваш код будет выглядеть так:
Вид
import json
@app.route('/')
def my_view():
data = [1, "foo"]
return render_template('index.html', data=map(json.dumps, data))
Шаблон
{% for item in data %}
<span onclick=someFunction({{ item|safe }});>{{ item }}</span>
{% endfor %}
Изменить 2
В моем примере я использую Flask
, я не знаю, какую инфраструктуру вы используете, но вы поняли, что вам просто нужно, чтобы она соответствовала используемой структуре.
Редактировать 3 (Предупреждение о безопасности)
НИКОГДА НЕ СОХРАНЯЙТЕ ЭТО С ПОСТАВЩИМИ ПОЛЬЗОВАТЕЛЕМ, ТОЛЬКО СДЕЛАЙТЕ ЭТО С ДОВЕРЕННЫМИ ДАННЫМИ!
В противном случае вы можете подвергнуть ваше приложение уязвимостям XSS!
Ответ 2
У меня была аналогичная проблема с использованием Flask, но мне не пришлось прибегать к JSON. Я просто передал список letters = ['a','b','c']
с помощью render_template('show_entries.html', letters=letters)
и установил
var letters = {{ letters|safe }}
в моем javascript-коде. Jinja2 заменил {{ letters }}
на ['a','b','c']
, который javascript интерпретируется как массив строк.
Ответ 3
Я могу предложить вам подход, ориентированный на JavaScript, который упрощает работу с файлами javascript в вашем проекте.
Создайте раздел javascript в файле шаблона jinja и поместите все переменные, которые вы хотите использовать в ваших файлах javascript, в объекте window:
start.html
...
{% block scripts %}
<script type="text/javascript">
window.appConfig = {
debug: {% if env == 'development' %}true{% else %}false{% endif %},
facebook_app_id: {{ facebook_app_id }},
accountkit_api_version: '{{ accountkit_api_version }}',
csrf_token: '{{ csrf_token }}'
}
</script>
<script type="text/javascript" src="{{ url_for('static', filename='app.js') }}"></script>
{% endblock %}
Jinja заменит значения, и наш объект appConfig будет доступен из наших других файлов script:
App.js
var AccountKit_OnInteractive = function(){
AccountKit.init({
appId: appConfig.facebook_app_id,
debug: appConfig.debug,
state: appConfig.csrf_token,
version: appConfig.accountkit_api_version
})
}
Я отделил код javascript от html-документов таким образом, который проще в управлении и дружелюбен.