Eu quero usar o AngularJS com o Django, no entanto, ambos usam {{ }}
como tags de modelo. Existe uma maneira fácil de alterar um dos dois para usar outra tag de modelo personalizada?
Eu quero usar o AngularJS com o Django, no entanto, ambos usam {{ }}
como tags de modelo. Existe uma maneira fácil de alterar um dos dois para usar outra tag de modelo personalizada?
Respostas:
Para o Angular 1.0, você deve usar as apis $ interpolateProvider para configurar os símbolos de interpolação: http://docs.angularjs.org/api/ng.$interpolateProvider .
Algo assim deve fazer o truque:
myModule.config(function($interpolateProvider) {
$interpolateProvider.startSymbol('{[{');
$interpolateProvider.endSymbol('}]}');
});
Lembre-se de duas coisas:
{{ }}
em seus modelos, sua configuração as quebrará. ( correção pendente )Embora não haja nada que possamos fazer sobre o primeiro problema, exceto avisar as pessoas, precisamos resolver o segundo problema.
$interpolateProvider.startSymbol('{[{').endSymbol('}]}');
você pode tentar textualmente a tag template Django e usá-la assim:
<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 você separou as seções da página corretamente, poderá usar facilmente as tags angularjs no escopo "bruto".
Em jinja2
{% raw %}
// here you can write angularjs template tags.
{% endraw %}
No modelo do Django (acima de 1,5)
{% verbatim %}
// here you can write angularjs template tags.
{% endverbatim %}
Criamos um filtro muito simples no Django 'ng' que facilita a mistura dos dois:
foo.html:
...
<div>
{{ django_context_var }}
{{ 'angularScopeVar' | ng }}
{{ 'angularScopeFunction()' | ng }}
</div>
...
O ng
filtro fica assim:
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)
Então, recebi uma grande ajuda no canal Angular IRC hoje. Acontece que você pode alterar as tags de modelo do Angular com muita facilidade. Os snippets necessários abaixo devem ser incluídos após a inclusão angular (o exemplo fornecido aparece nas listas de discussão e seria usado (())
como as novas tags de modelo, substituindo as suas):
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);
});
Além disso, apontei para um aprimoramento futuro que irá expor startSymbol
e endSymbol
propriedades que podem ser definidas para as tags que você desejar.
Eu voto contra o uso de parênteses duplos (()) como tag de modelo. Pode funcionar bem desde que nenhuma chamada de função esteja envolvida, mas, quando tentada, a seguinte
ng:disabled=(($invalidWidgets.visible()))
com o Firefox (10.0.2) no Mac, recebi um erro terrivelmente longo, em vez da lógica pretendida. <[]> correu bem para mim, pelo menos até agora.
Editar 2012-03-29: Observe que $ invalidWidgets está obsoleto. No entanto, eu ainda usaria outro invólucro além de aparelho duplo. Para qualquer versão angular superior a 0.10.7 (eu acho), você pode alterar o wrapper muito mais facilmente na definição de seu aplicativo / módulo:
angular.module('YourAppName', [], function ($interpolateProvider) {
$interpolateProvider.startSymbol('<[');
$interpolateProvider.endSymbol(']>');
});
(())
, só queria poder configurar os delimitadores.
Achei o código abaixo útil. Encontrei o código aqui: 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>
ela é renderizada como {{location}}
- sim, com chaves! Ele não renderiza o valor de $ scope.location que está codificado no meu controlador. Alguma idéia do que estou perdendo?
Você sempre pode usar ng-bind em vez de {{}} http://docs.angularjs.org/api/ng/directive/ngBind
<span ng-bind="name"></span>
Se você usa o django 1.5 e o uso mais recente:
{% verbatim %}
{{if dying}}Still alive.{{/if}}
{% endverbatim %}
Se você estiver com o django 1.2 no appengine, estenda a sintaxe do django com o comando verbatim template 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))
No seu arquivo, use:
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
para: from google.appengine._internal.django import template
Então, no meu arquivo principal, alterei o nome do arquivo: template.register_template_library('utilities.verbatim_template_tag')
Você pode dizer ao Django para saída {{
e }}
, assim como outras seqüências de modelo reservadas, usando a {% templatetag %}
tag
Por exemplo, usando {% templatetag openvariable %}
seria produzido {{
.
Eu ficaria com uma solução que usa as tags django {{}} e também angularjs {{}} com uma seção literal ou um modelo de etiqueta de modelo.
Isso é simplesmente porque você pode alterar a maneira como o angularjs funciona (conforme mencionado) através do $ interpolateProvider.startSymbol $ interpolateProvider.endSymbol, mas se você começar a usar outros componentes do angularjs como o ui-bootstrap, verá que alguns dos modelos JÁ estão criados com tags angularjs padrão {{}}.
Por exemplo, consulte https://github.com/angular-ui/bootstrap/blob/master/template/dialog/message.html .
Se você fizer alguma interpolação no servidor, a única maneira correta de fazer isso é com<>
$interpolateProvider.startSymbol('<{').endSymbol('}>');
Qualquer outra coisa é um vetor XSS.
Isso ocorre porque quaisquer delimitadores angulares que não são escapados pelo Django podem ser inseridos pelo usuário na cadeia de caracteres interpolada; se alguém definir seu nome de usuário como "{{evil_code}}", o Angular o executará com prazer . Se você usar um personagem para escapar do Django , isso não acontecerá.
templates
diretório django , o resto eu colocostatic
. Dessa forma, você não tem interferência. Há um tutorial que eu escrevi aqui: coderwall.com/p/bzjuka/...