Pregunta

Quiero usar angularjs con django, sin embargo, ambos usan {{ }} Como sus etiquetas de plantilla. ¿Hay una manera fácil de cambiar uno de los dos para usar alguna otra etiqueta de plantilla personalizada?

¿Fue útil?

Solución

Para Angular 1.0 debe usar las API $ InterpolateProvider para configurar los símbolos de interpolación: http://docs.angularjs.org/api/ng.$interpolateProvider.

Algo como esto debería hacer el truco:

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

Tenga en cuenta dos cosas:

  • Mezclar plantillas del lado del servidor y del lado del cliente rara vez es una buena idea y debe usarse con precaución. Los principales problemas son: mantenibilidad (difícil de leer) y seguridad (la doble interpolación podría exponer un nuevo vector de seguridad, por ejemplo, mientras se puede escapar de la plantilla de servidor y clientes por sí mismos, su combinación podría no ser).
  • Si comienza a usar directivas (componentes) de terceros que usan {{ }} En sus plantillas, su configuración las romperá. (Arreglar pendiente)

Si bien no hay nada que podamos hacer sobre el primer problema, excepto para advertir a las personas, debemos abordar el segundo problema.

Otros consejos

tal vez puedas intentar literal Etiqueta de plantilla de Django y úsela así:

<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 %}

Si hizo secciones separadas de la página correctamente, puede usar fácilmente etiquetas AngularJS en el alcance de la etiqueta "en bruto".

En jinja2

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

En plantilla de Django (por encima de 1.5)

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

Creamos un muy Filtro simple en django 'ng' que facilita la mezcla de los dos:

foo.html:

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

los ng El filtro se ve así:

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)

Así que hoy obtuve una gran ayuda en el canal Angular IRC. Resulta que puede cambiar las etiquetas de plantilla de Angular muy fácilmente. Los fragmentos necesarios a continuación deben incluirse después de su inclusión angular (el ejemplo dado aparece en su listas de correo y usaría (()) Como la nueva plantilla etiqueta, sustituya la suya):

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

Además, me señalaron una próxima mejora que expondrá startSymbol y endSymbol Propiedades que se pueden configurar en las etiquetas que desee.

Voto en contra de usar paréntesis dobles (()) como etiqueta de plantilla. Puede funcionar bien siempre que no se involucre ninguna llamada de función, pero cuando se prueba lo siguiente

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

Con Firefox (10.0.2) en Mac obtuve un error terriblemente largo en lugar de la lógica prevista. <[]> Me fue bien, al menos hasta ahora.

Editar 2012-03-29:Tenga en cuenta que $ InvalidWidgets está en desuso. Sin embargo, todavía usaría otro envoltorio que los tirantes dobles. Para cualquier versión angular superior a 0.10.7 (supongo), puede cambiar el envoltorio mucho más fácil en la definición de su aplicación / módulo:

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

Documentos de API.

Encontré el código a continuación útil. Encontré el código aquí: 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)

Siempre puedes usar NG-Bind en lugar de {{}}http://docs.angularjs.org/api/ng/directive/ngbind

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

Si usa Django 1.5 y un uso más nuevo:

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

Si está atascado con Django 1.2 en Appengine, extienda la sintaxis de Django con el comando de plantilla literal como este ...

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

En su archivo de archivo:

from google.appengine.ext.webapp import template
template.register_template_library('utilities.verbatim_template_tag')

Fuente:http://bamboobig.blogspot.co.at/2011/09/notebook-using-jquery-templates-in.html

Puedes decirle a Django que salga {{ y }}, así como otras cadenas de plantilla reservadas usando el {% templatetag %} etiqueta.

Por ejemplo, usando {% templatetag openvariable %} saldría {{.

Me quedaría con una solución que use ambas etiquetas Django {{}} también angularjs {{}} con una sección literal o templateTag.

Eso es simplemente porque puede cambiar la forma en que funciona AngularJS (como se mencionó) a través de $ interpolateProvider.StartSymbol $ InterpolateProvider.endSymbol Pero si comienza a usar otros componentes AngularJS como el UI-Bootstrap, encontrará que algunas de las plantillas ya están construidas con etiquetas AngularJS estándar {{}}.

Por ejemplo, mira https://github.com/angular-ui/bootstrap/blob/master/template/dialog/message.html.

Si hace alguna interpolación del lado del servidor, el solamente La forma correcta de hacer esto es con <>

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

Cualquier otra cosa es un vector XSS.

Esto se debe a que el usuario puede ingresar a los delimitadores angulares que el usuario no escape por Django en la cadena interpolada; Si alguien establece su nombre de usuario como "{{Evil_code}}", Angular felizmente lo ejecutará. Si usa un carácter que el django escapa, sin embargo, esto no sucederá.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top