如何将Python中的列表从Jinja2传递给JavaScript

我是JavaScript新手,目前我正在处理一个问题。 假设我有一个Pythonvariables:

listOfItems= ['1','2','3','4','5'] 

我通过呈现HTML将它传递给Jinja,并且在JavaScript中也有一个名为somefunction(variable)的函数。 我正在尝试传递'listOfItems'的每个项目。 我尝试了这样的事情:

 {% for item in listOfItems %}<br> <span onclick="somefunction({{item}})">{{item}}</span><br> {% endfor %} 

是否有可能从Python传递一个列表到JavaScript,或者我应该循环中的每一个从列表中的项目? 我怎样才能做到这一点?

为了将一些上下文数据传递给javascript代码,你必须以一种被javascript(即JSON)“理解”的方式对它进行序列化。 您还需要使用safe Jinjafilter将其标记为安全,以防止数据被转移。

你可以做到这一点,做到这一点:

风景

 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漏洞!

我有一个类似的问题使用Flask,但我不必诉诸于JSON。 我只是用render_template('show_entries.html', letters=letters)传递一个列表letters = ['a','b','c'] ,并设置

 var letters = {{ letters|safe }} 

在我的JavaScript代码。 Jinja2用{{ letters }} ['a','b','c']replace了{{ letters }} ,这个JavaScript被解释为一个string数组。

我可以build议你一个面向JavaScript的方法,这使得在你的项目中使用JavaScript文件很容易。

在你的jinja模板文件中创build一个javascript部分,并将你想要在JavaScript文件中使用的所有variables放在窗口对象中:

的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将会replace值,我们的appConfig对象可以从我们的其他脚本文件中获得:

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 }) } 

我用这种方式分离HTML文档的JavaScript代码,这是更容易pipe理和SEO友好。