Javascript 带有Django的AngularJS-模板标记冲突
我想在Django中使用AngularJS,但是它们都使用Javascript 带有Django的AngularJS-模板标记冲突,javascript,django,django-templates,angularjs,Javascript,Django,Django Templates,Angularjs,我想在Django中使用AngularJS,但是它们都使用{{}}作为模板标记。有没有一种简单的方法可以将这两个标记中的一个更改为使用其他自定义模板标记?您可以告诉Django使用标记输出{{和},以及其他保留的模板字符串 例如,使用{%templatetag openvariable%}将输出{{,因此我今天在Angular IRC频道中得到了一些很大的帮助。事实证明,您可以非常轻松地更改Angular的模板标记。以下必要的片段应包含在Angular include之后(给定的示例显示在其上,
{{}}
作为模板标记。有没有一种简单的方法可以将这两个标记中的一个更改为使用其他自定义模板标记?您可以告诉Django使用标记输出{{
和}
,以及其他保留的模板字符串
例如,使用
{%templatetag openvariable%}
将输出{{
,因此我今天在Angular IRC频道中得到了一些很大的帮助。事实证明,您可以非常轻松地更改Angular的模板标记。以下必要的片段应包含在Angular include之后(给定的示例显示在其上,并将使用(())
作为新的模板标记,代替您自己的模板标记):
另外,我还提到了一个即将推出的增强功能,它将公开
startSymbol
和endSymbol
属性,这些属性可以设置为您想要的任何标记。我反对使用双圆括号(())作为模板标记。只要不涉及函数调用,它可能工作得很好,但尝试以下操作时
ng:disabled=(($invalidWidgets.visible()))
在Mac上使用Firefox(10.0.2)时,我得到了一个非常长的错误,而不是预期的逻辑。对我来说很顺利,至少到目前为止是这样
编辑2012-03-29:
请注意,$invalidWidgets已被弃用。但是我仍然会使用另一个包装,而不是双括号。对于任何高于0.10.7的角度版本(我猜),您可以在应用程序/模块定义中更轻松地更改包装:
angular.module('YourAppName', [], function ($interpolateProvider) {
$interpolateProvider.startSymbol('<[');
$interpolateProvider.endSymbol(']>');
});
angular.module('YourAppName',[],函数($interpolateProvider){
$interpolateProvider.startSymbol(“”);
});
.您可以尝试使用Django模板标记
然后像这样使用它:
{%verbatim%}
10是{5+5}
{%endverbatim%}
对于Angular 1.0,您应该使用$interpolateProvider API来配置插值符号:
像这样的事情应该可以做到:
myModule.config(function($interpolateProvider) {
$interpolateProvider.startSymbol('{[{');
$interpolateProvider.endSymbol('}]}');
});
记住两件事:
- 混合使用服务器端和客户端模板很少是一个好主意,应该谨慎使用。主要问题是:可维护性(难以阅读)和安全性(双重插值可能会暴露一个新的安全向量-例如,服务器端和客户端模板本身的转义可能是安全的,但它们的组合可能不是)
- 如果您开始使用在其模板中使用
的第三方指令(组件),那么您的配置将破坏它们。(){{}
...
<div>
{{ django_context_var }}
{{ 'angularScopeVar' | ng }}
{{ 'angularScopeFunction()' | ng }}
</div>
...
我发现下面的代码很有用。我在这里找到了代码:
“”“
文件名:angularjs.py
用法:
{%ng Some.angular.scope.content%}
例如
{%load angularjs%}
{%ng yourName%}
"""
从django导入模板
register=template.Library()
类AngularJS(template.Node):
定义初始化(自身,位):
self.ng=位
def渲染(自身,ctx):
返回“{%s}}”%”。加入(self.ng[1:])
def do_角度(解析器、令牌):
位=标记。拆分内容()
返回角度(位)
register.tag('ng',do_)
如果您使用django 1.5及更新版本,请使用:
{% verbatim %}
{{if dying}}Still alive.{{/if}}
{% endverbatim %}
如果您在appengine上使用django 1.2,请使用下面的逐字模板命令扩展django语法
from django import template
register = template.Library()
class VerbatimNode(template.Node):
def __init__(self, text):
self.text = text
def render(self, context):
return self.text
@register.tag
def verbatim(parser, token):
text = []
while 1:
token = parser.tokens.pop(0)
if token.contents == 'endverbatim':
break
if token.token_type == template.TOKEN_VAR:
text.append('{{')
elif token.token_type == template.TOKEN_BLOCK:
text.append('{%')
text.append(token.contents)
if token.token_type == template.TOKEN_VAR:
text.append('}}')
elif token.token_type == template.TOKEN_BLOCK:
text.append('%}')
return VerbatimNode(''.join(text))
在您的文件中使用:
from google.appengine.ext.webapp import template
template.register_template_library('utilities.verbatim_template_tag')
资料来源:
如果您正确地分隔了页面的各个部分,那么您可以在“原始”标记范围内轻松使用angularjs标记 金贾2号
{% raw %}
// here you can write angularjs template tags.
{% endraw %}
在Django模板中(1.5以上)
我会坚持使用一种解决方案,它既使用django标记{{},也使用angularjs{{},并带有逐字段或templatetag 这仅仅是因为您可以通过$interpolateProvider.startSymbol$interpolateProvider.endSymbol更改angularjs的工作方式(如前所述),但是如果您开始使用其他angularjs组件,如ui引导,您会发现一些模板已经使用标准angularjs标记{{}构建
例如,看看。您可以始终使用ng bind而不是{{}
如果您执行任何服务器端插值,唯一正确的方法是使用
$interpolateProvider.startSymbol(“”);
其他任何东西都是XSS向量
这是因为用户可以将Django未转义的任何角度分隔符输入到插值字符串中;如果有人将其用户名设置为“{evil_code}}”,但是如果使用a,则不会发生这种情况。我知道这是可能的,但它很混乱……它会更干净(并且看起来不是太大的问题)模板标签可以在其中一个框架中简单地配置。最后,它只是在幕后进行字符串匹配…公平点。我没有想到这一点,但我并不特别提倡使用
(())
,我只是想能够配置分隔符。在angularjs 1.0中就是这样做的:var m=angular.module('myApp',[]);m.config(function($interpolateProvider){$interpolateProvider.startSymbol('(');$interpolateProvider.endSymbol(');});Angular IRC channel.fwiw对任何人来说,我在#angularjs找到了一个。虽然这是一个非常有效的解决方案,但在某些情况下,我希望能够使用服务器上的数据引导视图,这样会很快变得混乱。想想用户的用户名之类的事情,它不会改变,所以我只需将其写入服务器上的模板中,但不会改变我将用angular写一些东西。Verbatim是Django core标记的一部分,从1.5版开始:在Django 1.7中,您不需要加载Verbatim,因为它位于标准标记库中。您只需要使用标记本身。如果有办法更改Django默认括号,那就太好了
from django import template
register = template.Library()
class VerbatimNode(template.Node):
def __init__(self, text):
self.text = text
def render(self, context):
return self.text
@register.tag
def verbatim(parser, token):
text = []
while 1:
token = parser.tokens.pop(0)
if token.contents == 'endverbatim':
break
if token.token_type == template.TOKEN_VAR:
text.append('{{')
elif token.token_type == template.TOKEN_BLOCK:
text.append('{%')
text.append(token.contents)
if token.token_type == template.TOKEN_VAR:
text.append('}}')
elif token.token_type == template.TOKEN_BLOCK:
text.append('%}')
return VerbatimNode(''.join(text))
from google.appengine.ext.webapp import template
template.register_template_library('utilities.verbatim_template_tag')
{% raw %}
// here you can write angularjs template tags.
{% endraw %}
{% verbatim %}
// here you can write angularjs template tags.
{% endverbatim %}
<span ng-bind="name"></span>
$interpolateProvider.startSymbol('<{').endSymbol('}>');