首页 文章

AngularJS与Django - 冲突的模板标签

提问于
浏览
290

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

13 回答

  • 17

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

    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)
    
  • 42

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

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

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

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

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

    API docs .

  • 29

    所以今天我在Angular IRC Channels 得到了很多帮助 . 事实证明,您可以非常轻松地更改Angular的模板标签 . 在你的角度包含之后,应该包含下面必要的片段(给定的例子出现在他们的mailing lists上,并使用 (()) 作为新的模板标签,替换你自己的):

    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);
    });
    

    此外,我被指出即将推出的增强功能,它将公开 startSymbolendSymbol 属性,可以设置为您想要的任何标签 .

  • 9

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

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

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

    请记住两件事:

    • 混合服务器端和客户端模板很少是一个好主意,应谨慎使用 . 主要问题是:可维护性(难以阅读)和安全性(双插值可能暴露出新的安全性向量 - 例如,当服务器端和客户端模板本身的模板化可能是安全的时,它们的组合可能不是) .

    • 如果您开始使用在其模板中使用 {{ }} 的第三方指令(组件),那么您的配置将破坏它们 . (fix pending

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

  • 3

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

    AngularJS module

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

    Webpage

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

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

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

    你可以试试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 %}
    
  • 15

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

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

    如果你坚持使用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))
    

    在您的文件中使用:

    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

  • 0

    如果您进行任何服务器端插值, only 正确的方法是使用 <>

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

    其他任何东西都是XSS向量 .

    这是因为任何未被Django转义的角度分隔符都可以由用户输入到插值字符串中;如果有人将其用户名设置为"{}",Angular will happily run it . 但是,如果使用character than Django escapes,则不会发生这种情况 .

  • 114

    我发现下面的代码很有帮助 . 我在这里找到了代码: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)
    
  • 11

    您可以通过使用{% templatetag %}标记告诉Django输出 {{}} 以及其他保留的模板字符串 .

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

  • 293

    如果你正确地分开了页面部分,那么你可以在“raw”标签范围内轻松使用angularjs标签 .

    在jinja2

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

    在Django模板中(1.5以上)

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

    我会坚持使用django标签{{}}以及angularjs {{}}和逐字段或模板标签的解决方案 .

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

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

相关问题