是否可以在Tornado中基于模板变量运行javascript代码?

MLi*_*ter 4 python tornado

如果处理程序返回变量以及模板:

self.render('page.html', enabled=enabled)
Run Code Online (Sandbox Code Playgroud)

其中enabled是一个布尔变量.

到目前为止,我知道我可以做以下事情:

{% if enabled %}
    ...
{% end %}
Run Code Online (Sandbox Code Playgroud)

在模板的HTML部分内.

但是我们可以enabled在Tornado模板中有条件地运行一些基于此变量的javascript代码吗?换句话说,我们可以在嵌入模板的javascript中访问此变量的值吗?

jsb*_*eno 6

当然 - 无论模板{% if ... %}{ % end %}指令之间的模板是什么,只有if表达式为True 时才会发送到浏览器.所以,在那里的任何东西,无论是<script >带有内联javascript的<link>标签,还是从某个地方导入javascript文件的标签,只会在这种情况下通过网络传输.

您甚至可以在Javascript代码本身中放置模板iffor指令,以根据服务器代码已知的条件启用或禁用部分代码.这个,无限嵌入或不是整块代码,我认为不会被视为一个好的实践 - 因为它会以不合需要的方式纠缠代码的服务器和客户端.

要从javascript访问变量,只需执行以下操作:

var enabled = {{enabled}};

{{...}}标记内的值使用服务器变量呈现.

在这种情况下,为了确保enabledPython和Javascript之间的兼容性,你应该使用0表示False,1表示True(因为如果使用Python布尔值,模板将呈现为 var enabled = True;- 这不是javascript所期望的,因为Javascript中保留的"true"是小写的)

唯一的限制是您只能在将页面发送到浏览器之前设置服务器端变量.因此,如果您需要在服务器端设置任何依赖于用户在所显示页面上的操作的变量,这种做法不会再削减它(只有页面重新加载).使页面在没有重新加载的情况下进行交互式更新的方法是依赖来自javascript的异步通信(以前称为"ajax").

编辑 - OP进一步询问:

这是一个问题:当我将一个字符串变量(例如myvar ='foo-bar')返回给模板时,当这个{{myvar}}在JS代码中得到评估时,JS显然将foo-bar解释为变量名而不是一个字符串.在这种情况下,它会导致错误,因为 - 表示减法.如何让JS将foo-bar识别为字符串值?

同样,正在发生的事情非常简单:{{ <expr> }}模板运算符插入了rsulting表达式的字符串表示 - 所以如果你在python myvar = "bla"和模板上var myvar = {{ myvar }},它被渲染(并以这种方式发送到客户端浏览器)var myvar = bla- 没有引号周围bla- 这就是javascript将其视为变量名称的原因.解决方法是在变量周围加上额外的引号,如果它是一个字符串,无论是在Python端还是在模板上.

在模板上,您可以: var myvar="{{ myvar }}"- 或者,在Python方面,在定义myvar时:myvar = '"%s"' % "bla"