带有Django的AngularJS – 冲突的模板标签

我想在Django中使用AngularJS,但是他们都使用{{ }}作为模板标签。 有没有简单的方法来改变其中一个使用其他自定义模板标签?

对于Angular 1.0,您应该使用$ interpolateProvider apis来configuration插值符号: http : //docs.angularjs.org/api/ng.$interpolateProvider 。

像这样的事情应该做的伎俩:

 myModule.config(function($interpolateProvider) { $interpolateProvider.startSymbol('{[{'); $interpolateProvider.endSymbol('}]}'); }); 

请记住两件事:

  • 混合服务器端和客户端模板很less是一个好主意,应谨慎使用。 主要的问题是:可维护性(难以阅读)和安全性(双重内插可能暴露一个新的安全载体 – 例如,当逃脱服务器端和客户端模板本身可能是安全的,他们的组合可能不会)。
  • 如果您开始使用在其模板中使用{{ }}的第三方指令(组件),那么您的configuration将会中断它们。 ( 修复未决 )

对于第一个问题,除了警告人之外,我们无能为力,但我们确实需要解决第二个问题。

你可以尝试逐字 Django模板标签,并使用它:

 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script> {% verbatim %} <div ng-app=""> <p>10 is {{ 5 + 5 }}</p> </div> {% endverbatim %} 

如果您正确地分隔页面的部分,那么您可以在“原始”标签范围内轻松使用angularjs标签。

在jinja2

 {% raw %} // here you can write angularjs template tags. {% endraw %} 

在Django模板(1.5以上)

 {% verbatim %} // here you can write angularjs template tags. {% endverbatim %} 

我们在Django'ng中创build了一个非常简单的filter,可以很容易地混合这两个filter:

foo.html:

 ... <div> {{ django_context_var }} {{ 'angularScopeVar' | ng }} {{ 'angularScopeFunction()' | ng }} </div> ... 

ng筛选器如下所示:

 from django import template from django.utils import safestring register = template.Library() @register.filter(name='ng') def Angularify(value): return safestring.mark_safe('{{%s}}' % value) 

所以我今天在Angular IRC频道得到了很多帮助。 事实certificate,你可以很容易地改变Angular的模板标签。 以下必要的代码片段应该包含在你的angular度包含之后(给出的例子出现在他们的邮件列表中 ,并将使用(())作为新的模板标签,替代你自己的):

 angular.markup('(())', function(text, textNode, parentElement){ if (parentElement[0].nodeName.toLowerCase() == 'script') return; text = text.replace(/\(\(/g,'{{').replace(/\)\)/g, '}}'); textNode.text(text); return angular.markup('{{}}').call(this, text, textNode, parentElement); }); angular.attrMarkup('(())', function(value, name, element){ value = value.replace(/\(\(/g,'{{').replace(/\)\)/, '}}'); element[0].setAttribute(name, value); return angular.attrMarkup('{{}}').call(this, value, name, element); }); 

另外,我指出了一个即将到来的增强function,可以将startSymbolendSymbol属性设置为任何您想要的标签。

我反对使用双括号(())作为模板标签。 只要没有涉及函数调用,但是在尝试以下操作时,它可能工作正常

 ng:disabled=(($invalidWidgets.visible())) 

与Firefox(10.0.2)在Mac我得到了一个非常长的错误,而不是预期的逻辑。 至less到目前为止,我的工作进展顺利。

编辑2012-03-29:请注意,$ invalidWidgets已弃用。 但是,我仍然使用另一个包装比双大括号。 对于任何高于0.10.7的angular度版本(我猜)你可以在你的应用程序/模块定义中更容易地改变包装:

 angular.module('YourAppName', [], function ($interpolateProvider) { $interpolateProvider.startSymbol('<['); $interpolateProvider.endSymbol(']>'); }); 

API文档 。

我发现下面的代码很有帮助。 我在这里find了代码: http : //djangosnippets.org/snippets/2787/

 """ filename: angularjs.py Usage: {% ng Some.angular.scope.content %} eg {% load angularjs %} <div ng-init="yourName = 'foobar'"> <p>{% ng yourName %}</p> </div> """ from django import template register = template.Library() class AngularJS(template.Node): def __init__(self, bits): self.ng = bits def render(self, ctx): return "{{%s}}" % " ".join(self.ng[1:]) def do_angular(parser, token): bits = token.split_contents() return AngularJS(bits) register.tag('ng', do_angular) 

你可以使用ng-bind代替{{}} http://docs.angularjs.org/api/ng/directive/ngBind

 <span ng-bind="name"></span> 

如果你使用django 1.5和更新的用法:

  {% verbatim %} {{if dying}}Still alive.{{/if}} {% endverbatim %} 

如果你坚持使用django 1.2在appengine上扩展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') 

资料来源: http : //bamboobig.blogspot.co.at/2011/09/notebook-using-jquery-templates-in.html

对于AngularJS v1.3.3,你应该像这样定义你自己的模板标签

AngularJS模块

 angular.module('myapp', []).config(function($interpolateProvider) { $interpolateProvider.startSymbol('{$'); $interpolateProvider.endSymbol('$}'); }); 

网页

 <a>{$ variable $}</a> 

您可以通过使用{% templatetag %}标记来告诉Django输出{{}}以及其他保留的模板string。

例如,使用{% templatetag openvariable %}会输出{{

我坚持使用django标记{{}}以及angularjs {{}}与逐字节或templatetag的解决scheme。

这只是因为你可以通过$ interpolateProvider.startSymbol $ interpolateProvider.endSymbol改变angularjs的工作方式(如上所述),但是如果你开始使用其他的angularjs组件如ui-bootstrap,你会发现一些模板已经build立了使用标准的angularjs标签{{}}。

例如看看https://github.com/angular-ui/bootstrap/blob/master/template/dialog/message.html

如果你做任何服务器端插值, 唯一正确的方法是使用<>

 $interpolateProvider.startSymbol('<{').endSymbol('}>'); 

其他任何东西都是XSSvector。

这是因为任何没有被Django转义的angular度分隔符都可以被用户input到插入的string中; 如果有人设置他们的用户名为“{{evil_code}}”, Angular会很高兴地运行它 。 如果你使用一个字符而不是Django转义 ,然而,这不会发生。