Quiero usar AngularJS con Django, sin embargo, ambos lo usan {{ }}
como etiquetas de plantilla. ¿Hay una manera fácil de cambiar uno de los dos para usar alguna otra etiqueta de plantilla personalizada?
Quiero usar AngularJS con Django, sin embargo, ambos lo usan {{ }}
como etiquetas de plantilla. ¿Hay una manera fácil de cambiar uno de los dos para usar alguna otra etiqueta de plantilla personalizada?
Respuestas:
Para Angular 1.0, debe usar la 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:
{{ }}
en sus plantillas, entonces su configuración las romperá. ( arreglo pendiente )Si bien no hay nada que podamos hacer sobre el primer problema, excepto advertir a las personas, debemos abordar el segundo problema.
$interpolateProvider.startSymbol('{[{').endSymbol('}]}');
tal vez puedas probar la etiqueta de plantilla Django textualmente y usarla 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 separó las secciones de la página correctamente, puede usar fácilmente las etiquetas angularjs en el alcance de la etiqueta "en bruto".
En jinja2
{% raw %}
// here you can write angularjs template tags.
{% endraw %}
En la plantilla de Django (superior a 1.5)
{% verbatim %}
// here you can write angularjs template tags.
{% endverbatim %}
Creamos un filtro muy simple en Django 'ng' que facilita la mezcla de los dos:
foo.html:
...
<div>
{{ django_context_var }}
{{ 'angularScopeVar' | ng }}
{{ 'angularScopeFunction()' | ng }}
</div>
...
El ng
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 obtuve una gran ayuda en el canal Angular IRC hoy. Resulta que puedes cambiar las etiquetas de plantilla de Angular muy fácilmente. Los fragmentos necesarios a continuación se deben incluir después de su inclusión angular (el ejemplo dado aparece en sus listas de correo y se usaría (())
como las nuevas etiquetas de plantilla, en lugar de las suyas propias):
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 las endSymbol
propiedades que se pueden configurar para cualquier etiqueta que desee.
Voto en contra del uso de paréntesis dobles (()) como etiqueta de plantilla. Puede funcionar bien siempre que no exista una llamada a la función, pero cuando se intenta 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 otra envoltura que no sean llaves dobles. Para cualquier versión angular superior a 0.10.7 (supongo), podría cambiar el contenedor mucho más fácilmente en la definición de su aplicación / módulo:
angular.module('YourAppName', [], function ($interpolateProvider) {
$interpolateProvider.startSymbol('<[');
$interpolateProvider.endSymbol(']>');
});
API docs .
(())
, solo quería poder configurar los delimitadores.
Encontré el siguiente código ú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)
<p>{% ng location %}</p>
se muestra como {{location}}
- ¡sí con llaves! No representa el valor de $ scope.location, que está codificado en mi controlador. ¿Alguna idea de lo que me estoy perdiendo?
Siempre puede 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 reciente:
{% 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 textual 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 use:
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
from django import template
a: from google.appengine._internal.django import template
Luego, en mi archivo principal, solo cambié el nombre del archivo: template.register_template_library('utilities.verbatim_template_tag')
Puede decirle a Django que imprima {{
y }}
, al igual que otras cadenas de plantillas reservadas, use la {% templatetag %}
etiqueta.
Por ejemplo, usar {% templatetag openvariable %}
sería salida {{
.
Me quedaría con una solución que usa las etiquetas django {{}} y angularjs {{}} con una sección literal o una etiqueta de plantilla.
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 de angularjs como ui-bootstrap, encontrará que algunas de las plantillas YA están construidas YA. con etiquetas angulares estándar {{}}.
Por ejemplo, mire https://github.com/angular-ui/bootstrap/blob/master/template/dialog/message.html .
Si realiza una interpolación del lado del servidor, la única forma correcta de hacerlo es con<>
$interpolateProvider.startSymbol('<{').endSymbol('}>');
Cualquier otra cosa es un vector XSS.
Esto se debe a que el usuario puede ingresar cualquier delimitador angular que Django no haya escapado en la cadena interpolada; si alguien establece su nombre de usuario como "{{evil_code}}", Angular lo ejecutará felizmente . Sin embargo, si usa un personaje que Django escapa , esto no sucederá.
templates
directorio de django , el resto la pongostatic
. De esa manera no tienes interferencia. Hay un tutorial que escribí aquí: coderwall.com/p/bzjuka/…