AngularJS与Django - 冲突的模板标签

End*_*age 299 javascript django django-templates angularjs

我想将AngularJS与Django一起使用,但它们都{{ }}用作模板标签.有没有一种简单的方法来改变其中一个使用其他自定义模板标签?

Igo*_*nar 296

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

像这样的东西应该做的伎俩:

myModule.config(function($interpolateProvider) {
  $interpolateProvider.startSymbol('{[{');
  $interpolateProvider.endSymbol('}]}');
});
Run Code Online (Sandbox Code Playgroud)

请记住两件事:

  • 混合服务器端和客户端模板很少是一个好主意,应谨慎使用.主要问题是:可维护性(难以阅读)和安全性(双重插值可能会暴露出新的安全性向量 - 例如,虽然逃避服务器端和客户端模板本身可能是安全的,但它们的组合可能不是这样).
  • 如果您开始使用{{ }}在其模板中使用的第三方指令(组件),那么您的配置将破坏它们.(修复待定)

虽然我们无法对第一个问题采取任何措施,但警告人员除外,我们确实需要解决第二个问题.

  • 因为$ interpolateProvider在用作setter时返回self,所以这是一个稍微紧凑的版本:`$ interpolateProvider.startSymbol('{[{').endSymbol('}]}');` (12认同)
  • 看起来"修复"已关闭.这是否意味着使用第三方组件现在不安全? (5认同)
  • 您是否介意解释您的第一点(维护,安全性以及混合服务器端和客户端模板的其他问题)?多一点解释会有所帮助. (4认同)

小智 120

你可以试试verbatim 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 %}
Run Code Online (Sandbox Code Playgroud)

  • 从版本1.5开始,Verbatim是Django核心标记的一部分:https://docs.djangoproject.com/en/dev/ref/templates/builtins/?from = olddocs#verbatim (16认同)
  • 在Django 1.7中,您不需要逐字加载,因为它在标准标记库中.您只需要自己使用标签. (11认同)

tha*_*ote 42

如果您正确地分开了页面部分,那么您可以在"原始"标记范围内轻松使用angularjs标记.

在jinja2

{% raw %}
    // here you can write angularjs template tags.
{% endraw %}
Run Code Online (Sandbox Code Playgroud)

在Django模板中(1.5以上)

{% verbatim %}    
    // here you can write angularjs template tags.
{% endverbatim %}
Run Code Online (Sandbox Code Playgroud)


Wes*_*aro 29

我们在Django'ng'中创建了一个非常简单的过滤器,可以很容易地混合两者:

foo.html:

...
<div>
  {{ django_context_var }}
  {{ 'angularScopeVar' | ng }}
  {{ 'angularScopeFunction()' | ng }}
</div>
...
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)


End*_*age 26

所以今天我在Angular IRC频道得到了很多帮助.事实证明,您可以非常轻松地更改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);
});
Run Code Online (Sandbox Code Playgroud)

此外,我还指出了即将发布的增强功能,它将公开startSymbolendSymbol属性设置为您想要的任何标签.

  • 这就是你在angularjs 1.0中的表现:var m = angular.module('myApp',[]); m.config(function($ interpolateProvider){$ interpolateProvider.startSymbol('(('); $ interpolateProvider.endSymbol('))');}); (17认同)

小智 17

我反对使用双括号(())作为模板标签.只要不涉及函数调用但是在尝试以下时它可能会很好地工作

ng:disabled=(($invalidWidgets.visible()))
Run Code Online (Sandbox Code Playgroud)

使用Mac上的Firefox(10.0.2)我得到了一个非常长的错误而不是预期的逻辑.<[]>对我来说很顺利,至少到现在为止.

编辑2012-03-29: 请注意,$ invalidWidgets已弃用.但是我仍然使用另一个包装而不是双括号.对于任何高于0.10.7的角度版本(我猜),您可以在应用程序/模块定义中更轻松地更改包装:

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

API文档.


nu *_*est 15

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

"""
filename: angularjs.py

Usage:
    {% ng Some.angular.scope.content %}

e.g.
    {% 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)
Run Code Online (Sandbox Code Playgroud)


小智 14

您总是可以使用ng-bind而不是{{}} http://docs.angularjs.org/api/ng/directive/ngBind

<span ng-bind="name"></span>
Run Code Online (Sandbox Code Playgroud)


cat*_*cat 11

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

  {% verbatim %}
    {{if dying}}Still alive.{{/if}}
  {% endverbatim %}
Run Code Online (Sandbox Code Playgroud)

如果你坚持使用django 1.2 on appengine使用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))
Run Code Online (Sandbox Code Playgroud)

在您的文件中使用:

from google.appengine.ext.webapp import template
template.register_template_library('utilities.verbatim_template_tag')
Run Code Online (Sandbox Code Playgroud)

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


Tho*_*zco 7

你可以告诉Django输出{{}}使用,以及其他保留模板字符串{% templatetag %}标签.

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

  • 我知道这是可能的,但它很混乱......模板标签只需在其中一个框架中配置就会更清晰(并且似乎没有太大的要求).在一天结束时,它只是在幕后进行字符串匹配...... (3认同)