[Разработка веб-сайтов, HTML, Angular, TypeScript] Bindon: малоизвестные фишки шаблонов Angular
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Недавно вышел Angular 12, а вместе с ним в шаблоны подвезли оператор нулевого слияния (??). Но что еще умеют шаблоны Angular, о чем вы, возможно, и не слышали? Давайте разберемся!
ngProjectAsПроекция контента в Angular похожа на систему слотов Web Components. Вы можете написать просто <ng-content></ng-content> — и все, что вы поместите внутрь вашего компонента, будет спроецировано туда.Вы также можете добавить несколько тэгов контента и проецировать отдельные части содержимого в разные места через атрибут select, как на примере ниже:
@Component({
selector: 'layout',
template: `
<ng-content select="header"></ng-content>
<main>
<ng-content select="aside"></ng-content>
<ng-content></ng-content>
</main>
<ng-content select="footer"></ng-content>
`,
styles: [
`
:host {
height: 100%;
display: flex;
flex-direction: column;
}
main {
display: flex;
flex: 1;
}
`
]
})
export class LayoutComponent {}
Такому компоненту можно передать содержимое следующим образом:
<layout>
<header>Header</header>
<aside>Sidebar</aside>
<footer>Footer</footer>
I am content
</layout>
Но что, если вы хотите спроецировать текст, не оборачивая его DOM-элементом? Или, например, поместить блок из нескольких элементов в один слот? Тогда можно использовать тэг ng-container, пометив его атрибутом ngProjectAs. Вот пример:https://stackblitz.com/edit/angular-content-selectionСовсем недавно на angular.io добавили отдельную статью о проецировании контента.ngNonBindableДопустим, вы хотите вывести на страницу пример интерполяции фигурными скобками, показав как есть: <div>Hello, {{userName}}</div>. Но, если вы хотите вывести непосредственно фигурные скобки, их нужно экранировать. Иначе Angular попытается их обработать. Добавьте одну { в шаблон. Вы увидите следующее сообщение:
Do you have an unescaped "{" in your template? Use "{{ '{' }}") to escape it.
Писать пять скобок вместо одной — это перебор. Возможно, вы подумали про изменение символа интерполяции для этого компонента, но это не поможет. Свой символ интерполяции только добавляет альтернативу, а не заменяет символ по умолчанию.На помощь приходит ngNonBindable. Это директива компилятора (как i18n), которая говорит ему относиться к этому куску как к простому HTML: <div ngNonBindable>Hello, {{userName}}</div>ngPreserveWhitespacesКак вы, наверное, знаете, Angular избавляет вас от головной боли пустых кусков в разметке, удаляя их при компиляции. Эту штуку можно отключить в angularCompilerOptions в tsconfig.json для всего проекта или в декораторе @Component для конкретного компонента.В целом это довольно полезная фишка, но иногда может быть необходимо отключить ее на небольшом куске шаблона. Еще одна директива компилятора может помочь с этим: просто поместите ngPreserveWhitespaces на элемент — и компилятор оставит все пробелы внутри в целости.&ngsp;В продолжение прошлого пункта: символ неразрывного пробела компилятор считает за пробел и удаляет. Если вы хотите его сохранить, есть специальный символ, хотите верьте, хотите нет, пришедший из Angular Dart — &ngsp;. Он переживет чистку компилятора и будет заменен на обычный .$any()Вам когда-то попадались библиотеки с кривыми типами? Например, вы оперируете немутабельными данными и хотите передать в инпут компонента массив. Но автор библиотеки указал в качестве типа обычный массив. TypeScript выдаст вам ошибку, указав, что ваш ReadOnly-массив не имеет мутабельных методов и не может быть передан в компонент. Или бывает, что указанный интерфейс в принципе некорректный, если мейнтейнер библиотеки не фанат TypeScript. В таком случае есть два действия, которые нужно предпринять:
- Обернуть ваш объект в специальную функцию $any: [value]="$any(value)".
- Пойти в GitHub библиотеки и завести PR, исправляющий типы.
Не забудьте про второй пункт, без него ничего не сработает!BindonУ вас не рябит в глазах от обилия специальных символов?
<my-component
#component
[@animation]=”animation”
[value]=”value”
[(banana)]=”twoWayBoundValue”
(output)=”onOutput($event)”
(click)=”onClick()”
></my-component>
А ведь есть альтернативный синтаксис, с помощью которого тот же шаблон можно записать без всех этих скобок:
<my-component
ref-component
bind-animate-animation=”animation”
bind-value=”value”
bindon-banana=”twoWayBoundValue”
on-output=”onOutput($event)”
on-click=”onClick()”
></my-component>
Честно говоря, не знаю, зачем так делать. Может быть, чтобы было легко сортировать байндинги по типу? В любом случае теперь вы тоже так умеете.БонусА вы знали, что, кроме ng-template, ng-container и ng-content, есть еще один встроенный тэг: ng-component. Это не совсем фишка шаблонов, но я впервые увидел его, изучая шаблон в DevTools, и меня эта находка удивила, так что я решил включить ее в статью.Может быть, вы догадаетесь, отчего он появляется в HTML? Небольшая подсказка: селектор в @Component необязателен.
@Component({
selector: 'app-root', // ←---- это поле опционально
...
})
Что же Angular может использовать для компонентов без селектора? Именно ng-component — автоматически созданный под них тэг. Но как компонент без селектора может оказаться в разметке? Его можно динамически создать с помощью *ngComponentOutlet или его может вставить Router.Знаете ли вы еще какие-то особенные, плохо задокументированные возможности шаблонов, которые я не упомянул? Поделитесь ими в комментариях! А то я нигде не встречал полного списка и собрал все это из личного опыта и путешествий по исходникам.
===========
Источник:
habr.com
===========
Похожие новости:
- [Разработка веб-сайтов, Программирование, Symfony] Главные причины, почему мы разрабатываем веб-приложения на Symfony (перевод)
- [WordPress, Разработка веб-сайтов, Серверная оптимизация] Выше 90 баллов PageSpeed на WordPress — это реально
- [Angular] Understanding & using RxJS in Angular
- [Информационная безопасность, Разработка веб-сайтов, Реверс-инжиниринг] Промокоды, случайно оставленные в исходном коде веб-сайта (перевод)
- [Разработка веб-сайтов, Хранилища данных] Основы понимания мира баз данных
- [Разработка веб-сайтов, NoSQL, ReactJS, Serverless] You don't know Redis
- [Angular] Getting To Learn About Angular Ivy
- [JavaScript, Node.JS, TypeScript, Микросервисы] Делаем микрообразы с микросервисами
- [Разработка веб-сайтов, JavaScript, IT-стандарты, VueJS, TypeScript] Vue 3: CompositionAPI + Typescript эксперименты
- [JavaScript, ReactJS, TypeScript] Готовим селекторы в Redux
Теги для поиска: #_razrabotka_vebsajtov (Разработка веб-сайтов), #_html, #_angular, #_typescript, #_angular, #_shablon (шаблон), #_template, #_typescript, #_blog_kompanii_tinkoff (
Блог компании TINKOFF
), #_razrabotka_vebsajtov (
Разработка веб-сайтов
), #_html, #_angular, #_typescript
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 24-Ноя 22:03
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Недавно вышел Angular 12, а вместе с ним в шаблоны подвезли оператор нулевого слияния (??). Но что еще умеют шаблоны Angular, о чем вы, возможно, и не слышали? Давайте разберемся! ngProjectAsПроекция контента в Angular похожа на систему слотов Web Components. Вы можете написать просто <ng-content></ng-content> — и все, что вы поместите внутрь вашего компонента, будет спроецировано туда.Вы также можете добавить несколько тэгов контента и проецировать отдельные части содержимого в разные места через атрибут select, как на примере ниже: @Component({
selector: 'layout', template: ` <ng-content select="header"></ng-content> <main> <ng-content select="aside"></ng-content> <ng-content></ng-content> </main> <ng-content select="footer"></ng-content> `, styles: [ ` :host { height: 100%; display: flex; flex-direction: column; } main { display: flex; flex: 1; } ` ] }) export class LayoutComponent {} <layout>
<header>Header</header> <aside>Sidebar</aside> <footer>Footer</footer> I am content </layout> Do you have an unescaped "{" in your template? Use "{{ '{' }}") to escape it.
<my-component
#component [@animation]=”animation” [value]=”value” [(banana)]=”twoWayBoundValue” (output)=”onOutput($event)” (click)=”onClick()” ></my-component> <my-component
ref-component bind-animate-animation=”animation” bind-value=”value” bindon-banana=”twoWayBoundValue” on-output=”onOutput($event)” on-click=”onClick()” ></my-component> @Component({
selector: 'app-root', // ←---- это поле опционально ... }) =========== Источник: habr.com =========== Похожие новости:
Блог компании TINKOFF ), #_razrabotka_vebsajtov ( Разработка веб-сайтов ), #_html, #_angular, #_typescript |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 24-Ноя 22:03
Часовой пояс: UTC + 5