web2py:如何将Python数组复制到JavaScript数组中

3 投票
3 回答
4384 浏览
提问于 2025-04-17 02:54

我现在在使用web2py时遇到了一个问题,就是让javascript和python之间能够互相沟通。

控制器:

def testDB():
        a=[]
        a.append('a')
        a.append('b')
        a.append('c')
        return dict(m=a)

(最终这部分会用数据库中的一系列数据来替代)目前我正在尝试把m中的值赋给javascript中的一个数组。我试过几种方法:

var t="{{=m}}";

结果返回了大约43个没有意义的字符。然后我又试了这个:

var t= new Array(); var i=0;"{{q=0}}"
"{{i=len(message)}}"
i="{{=i}}";
for(q=0;q<i;q++,"{{q=q+1}}"){
t[q]="{{m[q]}}";
}

但是失败了,因为python中的q变量在每次循环时都会重置,这正是我问题的关键。我还尝试过使用pop:

for(q=0;q<i;q++,"{{q=q+1}}"){
    alert("{{m.pop()}}");
    }

但数组在循环开始时又重置了,所以一直显示的是同一个变量。有没有更简单的方法来复制数组,或者防止python变量重置,或者干脆把javascript中的q变量直接插入到"{{m[q]}}"中呢?

根据我找到的信息,问题出在python是运行在服务器上的,所以你不能把javascript的值赋给它的变量,但我不太明白这和循环有什么关系(如果我在循环外做同样的事情,值就不会重置)。常见的解决办法似乎是使用ajax或json,但如果可以的话,我希望能避免这样。谢谢

3 个回答

2

Anthony的回答在web2py 2.9.12或更高版本上不适用。

要把Python变量的值赋给JavaScript变量,首先要在控制器中把它转换成JSON格式,然后再传递到视图中。在视图里,使用XML()来把它赋值给JavaScript变量,这样就不会被转义了。

控制器

from gluon.serializers import json

def index():
    array = [1, 2, 3, 4, 5]
    dictionary = dict(id=1, name='foo')
    return dict(array=json(array), dictionary=json(dictionary))

视图

<script>
    var js_array = {{=XML(array)}};
    var js_dictionary = {{=XML(dictionary)}};
</script>

另一种解决方案是使用ASSIGNJS这个助手。

控制器

def index():
    array = [1, 2, 3, 4, 5]
    dictionary = dict(id=1, name='foo')
    return dict(array=array, dictionary=dictionary)

视图

<script>
    {{=ASSIGNJS(js_array = array)}}
    {{=ASSIGNJS(js_dictionary = dictionary)}}
</script>
2

使用 json 模块:

>>> import json
>>> s = json.dumps(range(5))
>>> print repr(s)
'[0, 1, 2, 3, 4]'
>>> print json.loads(s)
[0, 1, 2, 3, 4]
>>>
6

在web2py(或者任何服务器端的模板语言)中,你不能像这样把服务器端的Python代码和客户端的Javascript代码混在一起。当你请求一个页面时,web2py视图中的Python代码会被执行,然后生成一个纯HTML页面(包括Javascript代码),这个页面会被返回给浏览器。浏览器只收到HTML,不会看到任何Python代码,也无法执行混合的Javascript和Python。

web2py视图只有在你使用{{=some_value}}(注意等号)时,才会把文本或代码插入到页面中。所以像{{m[q]}}这样的写法是没有效果的。如果你想看看浏览器从web2py接收到的内容,可以在浏览器中查看页面源代码——这样你就能看到你的视图生成的HTML/Javascript的最终结果。

至于你具体的问题,你可以使用response.json()把你的Python列表转换成一个JSON对象。不过,如果你直接把它放在视图中,它会把所有的引号转义,所以你需要把它传递给XML()助手来避免这种转义。大概是这样的:

var t = {{=XML(response.json(m))}}

撰写回答