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 ngfiltro è 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à startSymbole le endSymbolproprietà 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à.
templatesdirectory di django , il resto l'ho inseritostatic. In questo modo non hai interferenze. C'è un tutorial che ho scritto qui: coderwall.com/p/bzjuka/…