Voglio usare AngularJS con Django, ma entrambi usano {{ }}
come tag template. C'è un modo semplice per cambiare uno dei due per usare qualche altro tag di template personalizzato?
Voglio usare AngularJS con Django, ma entrambi usano {{ }}
come tag template. C'è un modo semplice per cambiare uno dei due per usare qualche altro tag di template personalizzato?
Risposte:
Per Angular 1.0 è necessario utilizzare le API $ interpolateProvider per configurare i simboli di interpolazione: http://docs.angularjs.org/api/ng.$interpolateProvider .
Qualcosa del genere dovrebbe fare il trucco:
myModule.config(function($interpolateProvider) {
$interpolateProvider.startSymbol('{[{');
$interpolateProvider.endSymbol('}]}');
});
Tieni a mente due cose:
{{ }}
nei loro modelli, la tua configurazione le interromperà. ( correzione in sospeso )Sebbene non ci sia nulla che possiamo fare per il primo problema, ad eccezione degli avvertitori, dobbiamo affrontare il secondo problema.
$interpolateProvider.startSymbol('{[{').endSymbol('}]}');
puoi forse provare il tag template integrale di Django e usarlo in questo modo:
<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 %}
Se le sezioni della pagina sono state separate correttamente, è possibile utilizzare facilmente i tag angularjs nell'ambito di tag "raw".
In jinja2
{% raw %}
// here you can write angularjs template tags.
{% endraw %}
Nel modello Django (sopra 1.5)
{% verbatim %}
// here you can write angularjs template tags.
{% endverbatim %}
Abbiamo creato un filtro molto semplice in Django 'ng' che semplifica il mix dei due:
foo.html:
...
<div>
{{ django_context_var }}
{{ 'angularScopeVar' | ng }}
{{ 'angularScopeFunction()' | ng }}
</div>
...
Il ng
filtro è simile al seguente:
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)
Quindi ho ricevuto un grande aiuto nel canale IRC angolare oggi. Si scopre che puoi cambiare facilmente i tag dei template di Angular. I frammenti necessari di seguito devono essere inclusi dopo l'inclusione angolare (l'esempio dato viene visualizzato nelle loro mailing list e verrà utilizzato (())
come nuovo tag modello, in sostituzione del proprio):
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);
});
Inoltre, sono stato indicato un miglioramento imminente che esporrà startSymbol
e le endSymbol
proprietà che possono essere impostate su qualsiasi tag desiderato.
Voto contro l'uso delle doppie parentesi (()) come tag modello. Può funzionare bene fino a quando non è coinvolta alcuna chiamata di funzione ma quando viene provato quanto segue
ng:disabled=(($invalidWidgets.visible()))
con Firefox (10.0.2) su Mac ho ricevuto un errore terribilmente lungo invece della logica voluta. <[]> è andato bene per me, almeno fino ad ora.
Modifica 29/03/2012: si noti che $ invalidWidgets è obsoleto. Comunque userei ancora un altro involucro rispetto alle doppie parentesi graffe. Per qualsiasi versione angolare superiore a 0.10.7 (suppongo) potresti cambiare il wrapper molto più facilmente nella definizione della tua app / modulo:
angular.module('YourAppName', [], function ($interpolateProvider) {
$interpolateProvider.startSymbol('<[');
$interpolateProvider.endSymbol(']>');
});
(())
, volevo solo essere in grado di configurare i delimitatori.
Ho trovato utile il codice qui sotto. Ho trovato il codice qui: 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>
viene reso come {{location}}
- sì con parentesi graffe! Non rende il valore di $ scope.location che è codificato nel mio controller. Qualche idea di cosa mi sto perdendo?
Puoi sempre usare ng-bind invece di {{}} http://docs.angularjs.org/api/ng/directive/ngBind
<span ng-bind="name"></span>
Se usi django 1.5 e versioni successive usa:
{% verbatim %}
{{if dying}}Still alive.{{/if}}
{% endverbatim %}
Se sei bloccato con django 1.2 su appengine estendi la sintassi di django con il comando modello testuale come questo ...
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))
Nel tuo file usa:
from google.appengine.ext.webapp import template
template.register_template_library('utilities.verbatim_template_tag')
Fonte: 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
Quindi, nel mio file principale, ho appena cambiato il nome del file: template.register_template_library('utilities.verbatim_template_tag')
Puoi dire a Django di produrre {{
e }}
, così come altre stringhe di template riservate, usando il {% templatetag %}
tag.
Ad esempio, usando {% templatetag openvariable %}
sarebbe output {{
.
Vorrei attenermi a una soluzione che utilizza sia i tag django {{}} che gli angularjs {{}} con una sezione testuale o templatetag.
Questo semplicemente perché puoi cambiare il modo in cui angularjs funziona (come detto) tramite $ interpolateProvider.startSymbol $ interpolateProvider.endSymbol ma se inizi a utilizzare altri componenti angularjs come ui-bootstrap scoprirai che alcuni dei modelli sono GIÀ costruiti con tag angularjs standard {{}}.
Ad esempio, guarda https://github.com/angular-ui/bootstrap/blob/master/template/dialog/message.html .
Se si esegue un'interpolazione sul lato server, l' unico modo corretto per farlo è con<>
$interpolateProvider.startSymbol('<{').endSymbol('}>');
Qualsiasi altra cosa è un vettore XSS.
Questo perché eventuali delimitatori angolari che non sfuggono a Django possono essere inseriti dall'utente nella stringa interpolata; se qualcuno imposta il suo nome utente su "{{evil_code}}", Angular lo eseguirà felicemente . Se usi un personaggio di cui Django sfugge , tuttavia, questo non accadrà.
templates
directory di django , il resto l'ho inseritostatic
. In questo modo non hai interferenze. C'è un tutorial che ho scritto qui: coderwall.com/p/bzjuka/…