Je veux utiliser AngularJS avec Django, mais ils utilisent tous les deux {{ }}
comme balises de modèle. Existe-t-il un moyen facile de modifier l'un des deux pour utiliser une autre balise de modèle personnalisée?
Je veux utiliser AngularJS avec Django, mais ils utilisent tous les deux {{ }}
comme balises de modèle. Existe-t-il un moyen facile de modifier l'un des deux pour utiliser une autre balise de modèle personnalisée?
Réponses:
Pour Angular 1.0, vous devez utiliser les API $ interpolateProvider pour configurer les symboles d'interpolation: http://docs.angularjs.org/api/ng.$interpolateProvider .
Quelque chose comme ça devrait faire l'affaire:
myModule.config(function($interpolateProvider) {
$interpolateProvider.startSymbol('{[{');
$interpolateProvider.endSymbol('}]}');
});
Gardez à l'esprit deux choses:
{{ }}
dans leurs modèles, votre configuration les cassera. ( correction en attente )Bien que nous ne puissions rien faire à propos du premier problème, sauf pour avertir les gens, nous devons régler le deuxième problème.
$interpolateProvider.startSymbol('{[{').endSymbol('}]}');
vous pouvez peut-être essayer la balise de modèle textuellement Django et l'utiliser comme ceci:
<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 vous avez correctement séparé les sections de la page, vous pouvez facilement utiliser les balises angularjs dans la portée de la balise "raw".
Dans jinja2
{% raw %}
// here you can write angularjs template tags.
{% endraw %}
Dans le modèle Django (supérieur à 1.5)
{% verbatim %}
// here you can write angularjs template tags.
{% endverbatim %}
Nous avons créé un filtre très simple dans Django 'ng' qui permet de mélanger facilement les deux:
foo.html:
...
<div>
{{ django_context_var }}
{{ 'angularScopeVar' | ng }}
{{ 'angularScopeFunction()' | ng }}
</div>
...
Le ng
filtre ressemble à ceci:
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)
J'ai donc obtenu une aide précieuse dans le canal IRC angulaire aujourd'hui. Il s'avère que vous pouvez modifier les balises de modèle d'Angular très facilement. Les extraits nécessaires ci-dessous doivent être inclus après votre inclusion angulaire (l'exemple donné apparaît sur leurs listes de diffusion et utiliserait (())
comme nouvelles balises de modèle, en remplacement de la vôtre):
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);
});
De plus, on m'a signalé une amélioration à venir qui exposera startSymbol
et des endSymbol
propriétés qui pourront être définies sur les balises que vous désirez.
Je vote contre l'utilisation de doubles parenthèses (()) comme balise de modèle. Cela peut bien fonctionner tant qu'aucun appel de fonction n'est impliqué, mais lorsque vous essayez ce qui suit
ng:disabled=(($invalidWidgets.visible()))
avec Firefox (10.0.2) sur Mac, j'ai eu une erreur terriblement longue au lieu de la logique voulue. <[]> s'est bien passé pour moi, du moins jusqu'à présent.
Edit 2012-03-29: Veuillez noter que $ invalidWidgets est déconseillé. Cependant, j'utiliserais toujours un autre wrapper que les accolades doubles. Pour toute version angulaire supérieure à 0.10.7 (je suppose), vous pouvez changer le wrapper beaucoup plus facilement dans la définition de votre application / module:
angular.module('YourAppName', [], function ($interpolateProvider) {
$interpolateProvider.startSymbol('<[');
$interpolateProvider.endSymbol(']>');
});
(())
, je voulais juste pouvoir configurer les délimiteurs.
J'ai trouvé le code ci-dessous utile. J'ai trouvé le code ici: 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>
elle est rendue comme {{location}}
- oui avec des accolades! Il ne rend pas la valeur de $ scope.location qui est codée en dur dans mon contrôleur. Une idée de ce qui me manque?
Vous pouvez toujours utiliser ng-bind au lieu de {{}} http://docs.angularjs.org/api/ng/directive/ngBind
<span ng-bind="name"></span>
Si vous utilisez django 1.5 et une utilisation plus récente:
{% verbatim %}
{{if dying}}Still alive.{{/if}}
{% endverbatim %}
Si vous êtes bloqué avec django 1.2 sur appengine, étendez la syntaxe django avec la commande de modèle verbatim comme ceci ...
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))
Dans votre fichier, utilisez:
from google.appengine.ext.webapp import template
template.register_template_library('utilities.verbatim_template_tag')
Source: http://bamboobig.blogspot.co.at/2011/09/notebook-using-jquery-templates-in.html
from django import template
à: from google.appengine._internal.django import template
Ensuite, dans mon fichier principal, changez simplement le nom de fichier: template.register_template_library('utilities.verbatim_template_tag')
Vous pouvez dire à Django de sortir {{
et }}
, ainsi que d'autres chaînes de modèle réservées, en utilisant la {% templatetag %}
balise.
Par exemple, l'utilisation {% templatetag openvariable %}
produirait {{
.
Je m'en tiendrai à une solution qui utilise à la fois les balises django {{}} ainsi que les angularjs {{}} avec une section verbatim ou un templatetag.
C'est simplement parce que vous pouvez changer la façon dont angularjs fonctionne (comme mentionné) via $ interpolateProvider.startSymbol $ interpolateProvider.endSymbol mais si vous commencez à utiliser d'autres composants angularjs comme le ui-bootstrap, vous constaterez que certains des modèles sont DÉJÀ construits avec des balises angularjs standard {{}}.
Par exemple, regardez https://github.com/angular-ui/bootstrap/blob/master/template/dialog/message.html .
Si vous effectuez une interpolation côté serveur, la seule façon correcte de le faire est de<>
$interpolateProvider.startSymbol('<{').endSymbol('}>');
Tout le reste est un vecteur XSS.
En effet, tout délimiteur angulaire non échappé par Django peut être entré par l'utilisateur dans la chaîne interpolée; si quelqu'un définit son nom d'utilisateur sur "{{evil_code}}", Angular l'exécute avec plaisir . Cependant, si vous utilisez un personnage que Django échappe , cela ne se produira pas.
templates
répertoire django , le reste que j'ai misstatic
. De cette façon, vous n'avez aucune interférence. Il y a un tutoriel que j'ai écrit ici: coderwall.com/p/bzjuka/…