Chcę używać AngularJS z Django, jednak oba używają {{ }}
jako znaczników szablonów. Czy istnieje prosty sposób na zmianę jednego z dwóch, aby użyć innego niestandardowego znacznika szablonów?
Chcę używać AngularJS z Django, jednak oba używają {{ }}
jako znaczników szablonów. Czy istnieje prosty sposób na zmianę jednego z dwóch, aby użyć innego niestandardowego znacznika szablonów?
Odpowiedzi:
W przypadku Angulara 1.0 należy użyć apis $ interpolateProvider do skonfigurowania symboli interpolacji: http://docs.angularjs.org/api/ng.$interpolateProvider .
Coś takiego powinno załatwić sprawę:
myModule.config(function($interpolateProvider) {
$interpolateProvider.startSymbol('{[{');
$interpolateProvider.endSymbol('}]}');
});
Pamiętaj o dwóch rzeczach:
{{ }}
ich szablonów, twoja konfiguracja je zepsuje. ( poprawka w toku )Chociaż nic nie możemy zrobić z pierwszym problemem, z wyjątkiem ostrzegania ludzi, musimy zająć się drugim problemem.
$interpolateProvider.startSymbol('{[{').endSymbol('}]}');
możesz spróbować dosłownie tagu szablonu Django i użyć go w następujący sposób:
<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 %}
Jeśli poprawnie rozdzieliłeś sekcje strony, możesz łatwo użyć tagów angularjs w zakresie „surowego” tagu.
W jinja2
{% raw %}
// here you can write angularjs template tags.
{% endraw %}
W szablonie Django (powyżej 1.5)
{% verbatim %}
// here you can write angularjs template tags.
{% endverbatim %}
Stworzyliśmy bardzo prosty filtr w Django 'ng', który ułatwia mieszanie dwóch:
foo.html:
...
<div>
{{ django_context_var }}
{{ 'angularScopeVar' | ng }}
{{ 'angularScopeFunction()' | ng }}
</div>
...
ng
Filtr wygląda następująco:
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)
Więc dzisiaj otrzymałem świetną pomoc w kanale Angular IRC. Okazuje się, że możesz bardzo łatwo zmieniać tagi szablonu Angulara. Niezbędne fragmenty poniżej powinny zostać uwzględnione po uwzględnieniu angulara (podany przykład pojawia się na ich listach mailingowych i posłużyłby (())
jako nowe tagi szablonu, zastępując własne):
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);
});
Wskazano także na nadchodzące ulepszenie, które ujawni startSymbol
i endSymbol
właściwości, które można ustawić na dowolne tagi.
Głosuję przeciwko użyciu podwójnego nawiasu (()) jako tagu szablonu. Może działać dobrze, o ile nie ma w nim wywołania funkcji, ale po wypróbowaniu następujących czynności
ng:disabled=(($invalidWidgets.visible()))
z Firefoksem (10.0.2) na Macu dostałem strasznie długi błąd zamiast zamierzonej logiki. <[]> szło mi dobrze, przynajmniej do tej pory.
Edytuj 2012-03-29: Pamiętaj, że $ invalidWidgets jest przestarzałe. Jednak nadal użyłbym innego opakowania niż podwójne szelki. W przypadku dowolnej wersji kątowej wyższej niż 0.10.7 (tak sądzę) można znacznie łatwiej zmienić opakowanie w definicji aplikacji / modułu:
angular.module('YourAppName', [], function ($interpolateProvider) {
$interpolateProvider.startSymbol('<[');
$interpolateProvider.endSymbol(']>');
});
(())
, po prostu chciałem móc skonfigurować ograniczniki.
Poniższy kod był pomocny. Znalazłem kod tutaj: 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>
zostanie renderowany jako {{location}}
- tak z nawiasami klamrowymi! Nie wyświetla wartości $ scope.location, która jest zapisana na stałe w moim kontrolerze. Masz pojęcie, czego mi brakuje?
Zawsze możesz użyć ng-bind zamiast {{}} http://docs.angularjs.org/api/ng/directive/ngBind
<span ng-bind="name"></span>
Jeśli używasz django 1.5 i nowszych:
{% verbatim %}
{{if dying}}Still alive.{{/if}}
{% endverbatim %}
Jeśli utkniesz z django 1.2 na appengine, rozszerz składnię django za pomocą polecenia szablonu verbatim w ten sposób ...
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))
W swoim pliku użyj:
from google.appengine.ext.webapp import template
template.register_template_library('utilities.verbatim_template_tag')
Źródło: http://bamboobig.blogspot.co.at/2011/09/notebook-using-jquery-templates-in.html
from django import template
na: from google.appengine._internal.django import template
Następnie, w moim głównym pliku, właśnie zmieniłem nazwę pliku: template.register_template_library('utilities.verbatim_template_tag')
Można powiedzieć Django do wyjścia {{
i }}
, jak również inne zastrzeżone ciągi szablon za pomocą {% templatetag %}
znacznika.
Na przykład użycie {% templatetag openvariable %}
spowoduje wyjście {{
.
Trzymałbym się rozwiązania, które wykorzystuje zarówno tagi django {{}}, jak i angularjs {{}} z sekcją dosłowną lub szablonem.
Jest tak po prostu dlatego, że możesz zmienić sposób działania angularjs (jak wspomniano) za pomocą $ interpolateProvider.startSymbol $ interpolateProvider.endSymbol, ale jeśli zaczniesz używać innych komponentów angularjs, takich jak ui-bootstrap, przekonasz się, że niektóre szablony są już zbudowane ze standardowymi tagami angularjs {{}}.
Na przykład spójrz na https://github.com/angular-ui/bootstrap/blob/master/template/dialog/message.html .
Jeśli wykonujesz interpolację po stronie serwera, jedynym prawidłowym sposobem na to jest użycie<>
$interpolateProvider.startSymbol('<{').endSymbol('}>');
Wszystko inne jest wektorem XSS.
Wynika to z faktu, że dowolne ograniczniki kątowe, które nie są poprzedzane przez Django, mogą zostać wprowadzone przez użytkownika do interpolowanego ciągu; jeśli ktoś ustawi swoją nazwę użytkownika na „{{evil_code}}”, Angular chętnie ją uruchomi . Jeśli użyjesz postaci, a Django ucieknie , tak się nie stanie.
templates
katalogu django , resztę wstawiamstatic
. W ten sposób nie będziesz mieć zakłóceń. Jest tutorial, który napisałem tutaj: coderwall.com/p/bzjuka/…