Перейти к содержанию

Введение в компоненты и шаблоны

📅 28.02.2022

Компонент компонента управляет участком экрана, называемым вид. Он состоит из класса TypeScript, шаблона HTML и таблицы стилей CSS. Класс TypeScript определяет взаимодействие

шаблона HTML и отрисованной структуры DOM, а таблица стилей описывает его внешний вид.

Приложение Angular использует отдельные компоненты для определения и управления различными аспектами приложения. Например, приложение может включать компоненты для описания:

  • корень приложения с навигационными ссылками
  • Список героев
  • Редактор героев

В следующем примере класс HeroListComponent включает:

  • Свойство heroes, которое содержит массив героев.
  • Свойство selectedHero, которое содержит последнего героя, выбранного пользователем.
  • Метод selectHero() устанавливает свойство selectedHero, когда пользователь щелкает мышью, чтобы выбрать героя из списка.

Компонент инициализирует свойство heroes с помощью сервиса HeroService, который является TypeScript свойством параметра на конструкторе. Система инъекции зависимостей Angular предоставляет компоненту сервис HeroService.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
export class HeroListComponent implements OnInit {
    heroes: Hero[] = [];
    selectedHero: Hero | undefined;

    constructor(private service: HeroService) {}

    ngOnInit() {
        this.heroes = this.service.getHeroes();
    }

    selectHero(hero: Hero) {
        this.selectedHero = hero;
    }
}

Angular создает, обновляет и уничтожает компоненты по мере того, как пользователь перемещается по приложению. Ваше приложение может предпринимать действия в каждый момент этого жизненного цикла с помощью необязательных lifecycle hooks, таких как ngOnInit().

Метаданные компонента

Metadata

Декоратор @Component идентифицирует класс, расположенный непосредственно под ним, как класс компонента и определяет его метаданные. В приведенном ниже примере кода видно, что HeroListComponent — это просто класс, без каких-либо специальных обозначений или синтаксиса Angular. Он не является компонентом, пока вы не пометите его как компонент с помощью декоратора @Component.

Метаданные компонента указывают Angular, где взять основные строительные блоки, необходимые для создания и представления компонента и его вида. В частности, он связывает шаблон с компонентом, либо непосредственно со встроенным кодом, либо по ссылке.

Вместе компонент и его шаблон описывают вид.

Помимо содержания шаблона или указания на него, метаданные @Component определяют, например, как на компонент можно ссылаться в HTML и какие службы ему требуются.

Вот пример основных метаданных для HeroListComponent.

1
2
3
4
5
6
7
8
@Component({
    selector: 'app-hero-list',
    templateUrl: './hero-list.component.html',
    providers: [HeroService],
})
export class HeroListComponent implements OnInit {
    /* . . . */
}

Этот пример показывает некоторые из наиболее полезных опций конфигурации @Component:

Параметры конфигурации Подробности
selector CSS-селектор, который указывает Angular создать и вставить экземпляр этого компонента везде, где он найдет соответствующий тег в HTML шаблона. Например, если HTML приложения содержит <app-hero-list></app-hero-list>, то Angular вставляет экземпляр представления HeroListComponent между этими тегами.
templateUrl Относительный к модулю адрес HTML-шаблона этого компонента. В качестве альтернативы, вы можете указать HTML-шаблон в строке, как значение свойства template. Этот шаблон определяет хостовое представление компонента.
providers Массив providers для сервисов, которые требуются компоненту. В примере это указывает Angular, как предоставить экземпляр HeroService, который конструктор компонента использует для получения списка героев для отображения.

Шаблоны и представления

Template

Вы определяете вид компонента с помощью сопутствующего шаблона. Шаблон — это форма HTML, которая указывает Angular, как отобразить компонент.

Представления обычно организованы иерархически, что позволяет изменять или показывать и скрывать целые разделы пользовательского интерфейса или страницы как единое целое. Шаблон, непосредственно связанный с компонентом, определяет хост-вид этого компонента.

Компонент также может определять иерархию представлений, которая содержит вложенные представления, размещенные в других компонентах.

Component tree

Иерархия представлений может включать представления из компонентов одного и того же NgModule и из компонентов разных NgModules.

Синтаксис шаблонов

Шаблон выглядит как обычный HTML, за исключением того, что он также содержит синтаксис Angular template syntax, который изменяет HTML на основе логики вашего приложения и состояния данных приложения и DOM. Ваш шаблон может использовать привязки данных для координации данных приложения и DOM, пайпы для преобразования данных перед их отображением и директивы для применения логики приложения к тому, что отображается.

Например, вот шаблон для компонента HeroListComponent учебника.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<h2>Hero List</h2>

<p><em>Select a hero from the list to see details.</em></p>
<ul>
    <li *ngFor="let hero of heroes">
        <button type="button" (click)="selectHero(hero)">
            {{hero.name}}
        </button>
    </li>
</ul>

<app-hero-detail
    *ngIf="selectedHero"
    [hero]="selectedHero"
></app-hero-detail>

Этот шаблон использует типичные элементы HTML, такие как <h2> и <p>. Он также включает элементы синтаксиса шаблона Angular, *ngFor, {{hero.name}}, (click), [hero] и <app-hero-detail>. Элементы синтаксиса шаблона указывают Angular, как вывести HTML на экран, используя программную логику и данные.

  • Директива *ngFor указывает Angular на итерацию списка.

  • {{hero.name}}, (click) и [hero] связывают данные программы с DOM и обратно, реагируя на ввод пользователя.

    Подробнее о связывании данных см. ниже.

  • Тег элемента <app-hero-detail> в примере представляет новый компонент, HeroDetailComponent.

    Компонент HeroDetailComponent определяет часть hero-detail визуализированной DOM-структуры, заданной компонентом HeroListComponent.

    Обратите внимание, как эти пользовательские компоненты смешиваются с родным HTML.

Привязка данных

Без фреймворка вы были бы ответственны за введение значений данных в элементы управления HTML и превращение ответов пользователя в действия и обновления значений. Написание такой логики вручную утомительно, чревато ошибками и является кошмаром для чтения, что может подтвердить любой опытный программист на JavaScript.

Angular поддерживает двустороннее связывание данных, механизм для координации частей шаблона с частями компонента. Добавьте разметку привязки данных в HTML шаблона, чтобы указать Angular, как соединить обе стороны.

На следующей диаграмме показаны четыре формы разметки привязки данных. Каждая форма имеет направление: к DOM, из DOM или и то, и другое.

Data Binding

Этот пример из шаблона HeroListComponent использует три таких формы.

1
2
3
4
<app-hero-detail [hero]="selectedHero"></app-hero-detail>
<button type="button" (click)="selectHero(hero)">
    {{hero.name}}
</button>
Связывание данных Подробнее
[hero] property binding Передает значение selectedHero из родительского HeroListComponent в свойство hero дочернего HeroDetailComponent.
(click) Вызывает метод компонента selectHero при нажатии пользователем на имя героя.
{{hero.name}} interpolation Отображает значение свойства hero.name компонента в элементе <button>.

Двусторонняя привязка данных (используется в основном в шаблонно-ориентированных формах) объединяет привязку свойств и событий в одной нотации. Приведем пример из шаблона HeroDetailComponent, в котором используется двусторонняя привязка данных с помощью директивы ngModel.

1
<input type="text" id="hero-name" [(ngModel)]="hero.name" />

При двустороннем связывании значение свойства данных поступает в поле ввода из компонента, как при связывании свойств. Изменения пользователя также возвращаются в компонент, сбрасывая свойство на последнее значение, как при привязке к событию.

Angular обрабатывает все привязки данных один раз для каждого цикла событий JavaScript, начиная с корня дерева компонентов приложения и заканчивая всеми дочерними компонентами.

Data Binding

Привязка данных играет важную роль в коммуникации между шаблоном и его компонентом, а также важна для коммуникации между родительскими и дочерними компонентами.

Parent/Child binding

Пайпы

Пайпы Angular позволяют объявлять преобразования отображения-значения в HTML шаблона. Класс с декоратором @Pipe определяет функцию, которая преобразует входные значения в выходные значения для отображения в представлении.

Angular определяет различные пайпы, такие как date и currency. Полный список см. в Pipes API list. Вы также можете определить новые пайпы.

Чтобы указать преобразование значений в шаблоне HTML, используйте оператор пайп (|).

1
{{interpolated_value | pipe_name}}

Вы можете объединять пайпы в цепочку, отправляя вывод одной функции пайпа для преобразования другой функцией пайпа. Пайп также может принимать аргументы, которые управляют тем, как она выполняет преобразование. Например, вы можете передать желаемый формат в функцию pipe date.

1
2
3
4
5
6
7
8
<!-- Default format: output 'Jun 15, 2015'-->
<p>Today is {{today | date}}</p>

<!-- fullDate format: output 'Monday, June 15, 2015'-->
<p>The date is {{today | date:'fullDate'}}</p>

<!-- shortTime format: output '9:43 AM'-->
<p>The time is {{today | date:'shortTime'}}</p>

Директивы

Directives

Шаблоны Angular являются динамическими. Когда Angular рендерит их, он преобразует DOM в соответствии с инструкциями, заданными директивами. Директива — это класс с декоратором @Directive().

Компонент технически является директивой. Однако компоненты настолько характерны и важны для приложений Angular, что Angular определяет декоратор @Component(), который расширяет декоратор @Directive() с функциями, ориентированными на шаблоны.

Помимо компонентов, есть еще два вида директив: структурные и атрибутивные. Angular определяет ряд директив обоих типов, и вы можете определить свои собственные с помощью декоратора @Directive().

Как и для компонентов, метаданные для директивы связывают декорированный класс с элементом selector, который используется для вставки в HTML. В шаблонах директивы обычно появляются в теге элемента как атрибуты, либо по имени, либо как цель присваивания или привязки.

Структурные директивы

Структурные директивы изменяют макет путем добавления, удаления и замены элементов в DOM. В примере шаблона используются две встроенные структурные директивы для добавления логики приложения к тому, как отображается представление.

1
2
<li *ngFor="let hero of heroes"></li>
<app-hero-detail *ngIf="selectedHero"></app-hero-detail>
Директивы Подробнее
*ngFor Итератив, который указывает Angular создавать по одному <li> на каждого героя в списке heroes.
*ngIf Безусловный, который включает компонент HeroDetail только в том случае, если выбранный герой существует.

Директивы атрибутов

Директивы Атрибутов изменяют внешний вид или поведение существующего элемента. В шаблонах они выглядят как обычные атрибуты HTML, отсюда и название.

Примером атрибутной директивы является директива ngModel, реализующая двустороннее связывание данных. ngModel изменяет поведение существующего элемента (обычно <input>), устанавливая его свойство display value и реагируя на события изменения.

1
<input type="text" id="hero-name" [(ngModel)]="hero.name" />

Angular включает предопределенные директивы, которые изменяют:

  • Структуру макета, например ngSwitch, и
  • Аспекты элементов и компонентов DOM, такие как ngStyle и ngClass.

Узнайте больше в руководствах Attribute Directives и Structural Directives.

Ссылки

Комментарии