Я хочу використовувати AngularJS з Django, однак вони обидва використовують {{ }}
як свої теги шаблонів. Чи є простий спосіб змінити один з двох, щоб використовувати якийсь інший спеціальний тег шаблону?
Я хочу використовувати AngularJS з Django, однак вони обидва використовують {{ }}
як свої теги шаблонів. Чи є простий спосіб змінити один з двох, щоб використовувати якийсь інший спеціальний тег шаблону?
Відповіді:
Для Angular 1.0 слід використовувати apis $ interpolateProvider для налаштування символів інтерполяції: http://docs.angularjs.org/api/ng.$interpolateProvider .
Щось подібне повинно зробити трюк:
myModule.config(function($interpolateProvider) {
$interpolateProvider.startSymbol('{[{');
$interpolateProvider.endSymbol('}]}');
});
Майте на увазі дві речі:
{{ }}
у своїх шаблонах, ваша конфігурація їх порушить. ( виправити очікування )Хоча ми нічого не можемо зробити з першого питання, крім попередження людей, нам потрібно вирішити другий випуск.
$interpolateProvider.startSymbol('{[{').endSymbol('}]}');
ви можете спробувати дослівно тег шаблону Django і використовувати його так:
<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 %}
Якщо ви зробили окремі розділи сторінки належним чином, ви можете легко використовувати теги angularjs у "сирі" області тегів.
В jinja2
{% raw %}
// here you can write angularjs template tags.
{% endraw %}
У шаблоні Джанго (вище 1,5)
{% verbatim %}
// here you can write angularjs template tags.
{% endverbatim %}
Ми створили дуже простий фільтр у Django 'ng', який спрощує їх змішування:
foo.html:
...
<div>
{{ django_context_var }}
{{ 'angularScopeVar' | ng }}
{{ 'angularScopeFunction()' | ng }}
</div>
...
ng
Фільтр виглядає наступним чином :
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)
Тому я сьогодні отримав велику допомогу в каналі Angular IRC. Виявляється, ви можете дуже легко змінити теги шаблонів Angular. Необхідні фрагменти нижче повинні бути включені після того, як ваш кутовий включить (даний приклад відображається у їхніх списках розсилки та використовуватиметься (())
як нові теги шаблону, замінюючи ваші власні):
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);
});
Крім того, мені було вказано на майбутнє вдосконалення, яке викриє startSymbol
та endSymbol
властивості, які можна встановити на будь-які теги, які ви хочете.
Я голосую проти використання подвійних дужок (()) як тегів шаблонів. Це може спрацьовувати до тих пір, поки не задіяний жоден функціональний виклик, але коли спробували наступне
ng:disabled=(($invalidWidgets.visible()))
з Firefox (10.0.2) на Mac я отримав жахливо довгу помилку замість призначеної логіки. <[]> добре пішов для мене, принаймні, до цих пір.
Редагувати 2012-03-29: Зверніть увагу, що $ invalidWidgets застаріло. Однак я все-таки використовую іншу обгортку, ніж подвійні брекети. Для будь-якої кутової версії, що перевищує 0.10.7 (я думаю), ви можете змінити обгортку набагато простіше у своєму визначенні програми / модуля:
angular.module('YourAppName', [], function ($interpolateProvider) {
$interpolateProvider.startSymbol('<[');
$interpolateProvider.endSymbol(']>');
});
(())
, я просто хотів мати можливість налаштувати роздільники.
Я знайшов код нижче корисним. Я знайшов тут код: 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>
він виводиться як {{location}}
- так, з фігурними дужками! Це не надає значення $ range.location, яке жорстко кодується в моєму контролері. Будь-яка ідея, що мені не вистачає?
Ви завжди можете використовувати ng-bind замість {{}} http://docs.angularjs.org/api/ng/directive/ngBind
<span ng-bind="name"></span>
Якщо ви використовуєте django 1.5 та новіші:
{% verbatim %}
{{if dying}}Still alive.{{/if}}
{% endverbatim %}
Якщо ви застрягли з django 1.2 на appengine, розгорніть синтаксис django за допомогою команди дослівного шаблону на зразок цього…
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))
У використанні вашого файлу:
from google.appengine.ext.webapp import template
template.register_template_library('utilities.verbatim_template_tag')
Джерело: http://bamboobig.blogspot.co.at/2011/09/notebook-using-jquery-templates-in.html
from django import template
на: from google.appengine._internal.django import template
Тоді в головному моєму файлі просто змінили ім'я файлу: template.register_template_library('utilities.verbatim_template_tag')
Ви можете сказати Django для виведення {{
та }}
, а також інших зарезервованих рядків шаблону, використовуючи {% templatetag %}
тег.
Наприклад, використання {% templatetag openvariable %}
буде виводити {{
.
Я б дотримувався рішення, яке використовує обидва теги django {{}}, а також angularjs {{}} або з дослівним розділом, або з шаблоном тегів.
Це просто тому, що ви можете змінити спосіб роботи angularjs (як уже згадувалося) за допомогою $ interpolateProvider.startSymbol $ interpolateProvider.endSymbol, але якщо ви почнете використовувати інші компоненти angularjs, такі як ui-bootstrap, ви побачите, що деякі шаблони ВЗАЄМО побудовані зі стандартними тегами angularjs {{}}.
Наприклад, подивіться на https://github.com/angular-ui/bootstrap/blob/master/template/dialog/message.html .
Якщо ви робите будь-яку інтерполяцію на стороні сервера, єдиний правильний спосіб це зробити<>
$interpolateProvider.startSymbol('<{').endSymbol('}>');
Все інше - вектор XSS.
Це тому, що будь-які кутові обмежувачі, які не виходять Джанго, можуть бути введені користувачем у інтерпольовану рядок; якщо хтось встановить своє ім'я користувача як "{{evil_code}}", Angular із задоволенням запустить його . Якщо ви використовуєте персонаж, ніж Джанго тікає , однак це не відбудеться.
templates
каталогу django , решту я вкладаюstatic
. Таким чином, у вас немає втручання. Тут я написав підручник: coderwall.com/p/bzjuka/…