Занятие 6.

Жизненный цикл и взаимодействие компонентов

SIS.Angular.2018

Кернер Денис

 

Обо мне

Работаю в СИС с 2009 г.

C 2012 года веду группу разработчиков. 

 

До 2015 года разрабатывал модули к системе федерального уровня для ПФР - ПТК АСВ. 

С 2015 года разрабатываю модули к системе Эталон.

 

В этом году перехожу со стека Intersystems Cache + Adobe Flex на 

Java и Angular.

 

В свободное время иногда пишу всякое на https://github.com/Bael

 

Из неформального:

Воспитываю с женой двоих сыновей. Или они нас.

Любимые писатели - Терри Пратчетт, Дэн Симмонс, Джим Батчер, Дэн Абнетт, Урсуна ле Гуин, Джордж Мартин 

 

План занятия

  • Вопросы по предыдущему занятию
  • Жизненный цикл
  • Взаимодействие компонентов. Туда и обратно
  • Практика. Kanban (управление задачами)
  • Итоги. Домашнее задание

Домашняя работа №5

Что понравилось:

1. Реализация вкладок и использование localStorage во многих работах

2. Код хорошо структурирован, разбираться в нем стало проще.
3. Улучшилось форматирование в работах.
4. Использование OnInit

В чем были проблемы:

1. Прямая работа с DOM.
2. Id в html.
3. Неиспользуемый код.
4. Беспорядок в репозиториях. 

У всего есть жизненный цикл:

Как компонент превращается в элемент HTML?

Создание

компонента

Инъекция зависимостей

Создание узла DOM (host) 

Повторить для дочерних компонентов

Запустить цикл отслеживания изменений (хуки)

Angular уничтожает элемент

Работа компонента

Хуки жизненного цикла компонента 

О чем нужно помнить:

 

Конструктор vs ngOnInit

В конструкторе - не должно быть тяжелой логики и загрузки данных. Это лучше делать в ngOnInit

Имплементируем интерфейсы

Это нужно делать обязательно, для того чтобы typescript знал об интерфейсах класса

Не забываем очистку на ngOnDestroy

Отписка от событий

Отписка от наблюдаемых объектов.

Сброс таймеров

Полезные ссылки

 

Взаимодействие компонентов

Зачем нужно обмениваться информацией?

 

Какие виды обмена данными внутри иерархии компонентов нам нужны?

 

 

От родительского к дочерним

Декоратор @Input() (в качестве параметра в декоратор можно передать alias)

 

Декоратор @Input() + setter (полезно в случае необходимости пост обработки введенных данных)

 

Template variable

Схема передачи данных

parent.component.ts

 

selectedStage:Stage

parent.component.html

<app-parent [stage]=selectedStage >

child.component.ts

 

@Input() stage;

Пример применения @Input:

import {Component, Input, OnInit} from '@angular/core';
import {Stage} from '../stage';

@Component({
  ...
})
export class StageComponent implements OnInit {
    @Input()
    stage: Stage; // можно также ставить декоратор на сеттер. 
<app-stage [stage]="selectedStage"></app-stage>
 selectedStage: Stage;

Класс родительского компонента

Шаблон родительского компонента

Класс дочернего компонента

От родительского к дочерним. Еще способы:

  • Переменная шаблона: #var

  • @ViewChild

  • ngOnChanges  - расширение идеи с @Input

  • Сервисы - рассмотрим через несколько занятий.

 

Переменная шаблона:

Переменная шаблона, она же template reference variable:

Именуется как #var.

Область действия - весь шаблон.

 

 

 

 <div class="seconds">{{timer.seconds}}</div>
 <app-countdown-timer #timer></app-countdown-timer>

От дочернего компонента к родителю

Шаблон дочернего компонента.html

 

при нажатии кнопки вызываем метод компонента

Дочерний компонент.ts 

Определяем @Output эмиттер и метод компонента для бросания события через эмиттер.

Шаблон родительского компонента.html

привязка метода для обработки события

Класс родительского компонента.html

метод для обработки события

Пример @Output: шаг 1 

 // Типизированный объект отправки событий (эмиттер) + декоратор 
 @Output()
 changeStage: EventEmitter<Task> = new EventEmitter<Task>();

// Функция которая будет бросать событие. 
// Обычно вызывается из шаблона компонента
 onSelected(stageName: string) {
    this.task.stage = 
        this.stages.find(val => val.name === stageName);
    this.changeStage.emit(this.task);
  }

Пример @Output: шаг 2

<app-task [task]="task" (changeStage)="onChangeTaskState($event)" >
</app-task>
  onChangeTaskState($event: Task) {
    this.tasks = this.tasks.filter(value => value !== $event);
  }

Полезные ссылки по взаимодействию компонентов

А как же практика?

Давайте применим полученные знания по @Input и @Output.

Давайте построим доску Kanban

Kanban 

По столбцам стадии решения задачи. В строках - задачи. Задачи вытягиваются вперед. 

Kanban 

Пример:

Структура приложения

Компонент доски

Компонент стадии №1

Компонент стадии №2

Компонент

задачи #1

Компонент

задачи #2

Шаг 1

Создаем компоненты

Board

Stage

Task

Шаг 2

Прокидываем данные сверху вниз

Шаг 3

Бросаем события снизу вверх

Шаг 3. Завершение

 

Стилизация и улучшения

Применение шаблонной переменной

 

 

 

Дополнительные ресурсы для изучения

Домашнее задание

  • Улучшаем канбан :)
  • Двигаем назад. Добавляем фичи.
  • Сдаем через неделю :)!

Спасибо за внимание!

Вопросы?

Занятие 6

By Сибирские интеграционные системы