#5 Angular2. Тур героев. Разбиваем код на компоненты

poster
В этом уроке мы научимся создавать компоненты и пробрасывать данные между ними в туре героев angular 2.
Понравилось? Поделитесь с друзьями!
Понравилось?
Поделитесь с друзьями!
Комментарии
Текст видео

Всем привет. Это пятый урок в серии "Тур героев" в angular 2. Так как наше приложение растет, то мы должны научиться создавать компоненты, которые можно будет реиспользовать, а также научиться пробрасывать данные из компоненты в компоненту.

Сейчас наш список героев и детальное отображение героя находится в одном файле. Они сейчас очень маленькие, но в реальном проекте они скорее всего разрастутся. Так же при создании компонента хорошо всегда руководствоваться принципом "single responsibility" - то есть единой ответственности. Поэтому, всегда лучше разбивать компоненты на мелкие, независимые блоки.

Поэтому давайте создадим для детального отображения героя свой собственный компонент. Создадим файл в папке app с названием hero-detail.component.ts и в нем опишем нам компонент.

Хочу заметить, что согласно конвенции наименований все файлы именуются через тире, а классы называются кемел-кейзом. Поэтому файл у нас называется hero-detail.component.ts, а класс HeroDetailComponent. Все наши компоненты заканчиваются словом component, чтобы мы их могли легко отличить.

import {Component, Input} from 'angular2/core';

@Component({
  selector: 'my-hero-detail',
})
export class HeroDetailComponent {
}

Итак что мы здесь сделали? Мы испортировали Component и Input с angular/core. Дальше мы создали декоратор и указали у него селектор my-hero-detail. Также мы создали заготовку для нашего класса.

Так как сейчас у нас в файле app.component.ts шаблон выбранного героя и список героев перемешан, то хорошо бы было это разделить. Для этого перенесем кусочек шаблона выбранного героя в наш новый компонент. Создадим в нем переменную template и внутрь выведем наш шаблон. Раньше мы работали с переменной selectedHero, а в этом компоненте она у нас будет называться hero. Так что нужно переименовать все переменные selectedHero на hero.

template: `
  <div *ngIf="hero">
    <h2>{{hero.name}} details!</h2>
    <div><label>id: </label>{{hero.id}}</div>
    <div>
      <label>name: </label>
      <input [(ngModel)]="hero.name" placeholder="name"/>
    </div>
  </div>
`

Также давайте опишем публичную переменную hero.

hero: Hero;

Как мы видим наш класс ничего не знает о типе данных Hero, но этот тип данных используется в обоих компонентах. Для того, чтобы он работал давайте вынесем класс Hero в отдельный файл hero.ts.

export class Hero {
  id: number;
  name: string;
}

Теперь мы можем легко импортировать этот класс в оба файла.

import {Hero} from './hero';

Наш компонент HeroDetailComponent должен знать какого героя отображать. Для этого нам нужно получать эти данные от родительского AppComponent, в котором мы как раз и будем создавать HeroDetailComponent. Но для начала нам нужно указать, что именно поле hero в классе будет использовано для биндинга. Для этого укажем над переменной hero декоратор @Input().

@Input()
hero: Hero;

Теперь давайте импортируем наш компонент в AppComponent, чтобы мы могли его подключить.

import {HeroDetailComponent} from './hero-detail.component';

И добавим в шаблон селектор компонента HeroDetailComponent.

<my-hero-detail></my-hero-detail>

Теперь нужно передать переменную selectedHero из AppComponent в HeroDetailComponent как переменную hero.

<my-hero-detail [hero]="selectedHero"></my-hero-detail>

Что тут происходит. Мы хотим, чтобы переменная selectedHero передалать в компонент, как переменная hero.

Если мы посмотрим в браузер и кликнем на какого-нибудь героя, то увидим, что при клике детальная информация не показывается и в консоли нет никаких ошибок. Вот это дебажить самый треш. На самом деле это все происходит потому, что ангулар не знает ничего о новом теге my-hero-detail, который мы использовали. Для того, чтобы оно заработало нужно добавить поле directives в декоратор AppComponent.

directives: [HeroDetailComponent]

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

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

Только зарегистрированные пользователи могут оставлять комментарии.  Войдите, пожалуйста.
Алексей Скоробогатов
1год назад назад
А есть какие-то примеры сайтов на Angulare, хотелось бы попробовать повторить - потренироваться.
monsterlessons
1год назад назад
У меня нет. Но вы можете зайти на github и в поиске написать angular blog, angular player или еще что-то и посмотреть проекты, которые вам интересны.
Stivn Cherenkor
2 лет назад
Ошибка при npm start: app/app.component.ts(69,21): error TS2304: Cannot find name 'hero''.
monsterlessons
2 лет назад
Посмотрите исходный код серии. Так сложно сказать где у вас ошибка. Также хочу напомнить, что серия снималась достаточно давно и код в ней будет работать 1 в 1 только с такими же версиями пакетов.
Stivn Cherenkor
2 лет назад
Очень оперативно, спасибо. Как оказалось, я написал hero не с заглавной. По этому и не компилировало.