Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Входные данные: input()

Входное свойство (input) — это поле компонента, значение которого задаёт родитель. Так один компонент можно использовать много раз с разными данными: например, компонент одной задачи выводится для каждой задачи списка.

Создание компонента задачи

ng generate component todo-item

Появится папка src/app/todo-item с файлами todo-item.ts, todo-item.html, todo-item.css и тестом.

Объявление входа

Функция input() создаёт входное свойство. Оно работает как сигнал только для чтения: значение читают вызовом со скобками.

// src/app/todo-item/todo-item.ts
import { Component, input } from '@angular/core';
 
@Component({
  selector: 'app-todo-item',
  templateUrl: './todo-item.html',
  styleUrl: './todo-item.css',
})
export class TodoItem {
  title = input('');
}
<!-- src/app/todo-item/todo-item.html -->
<span>{{ title() }}</span>

Аргумент input('') — значение по умолчанию: пока родитель ничего не передал, выводится пустая строка.

Передача значения из родителя

Родитель подключает компонент в imports и передаёт значение привязкой свойства:

// src/app/todo-list/todo-list.ts
import { Component, signal } from '@angular/core';
import { TodoItem } from '../todo-item/todo-item';
import { Todo } from '../todo';
 
@Component({
  selector: 'app-todo-list',
  imports: [TodoItem],
  templateUrl: './todo-list.html',
})
export class TodoList {
  todos = signal<Todo[]>([
    { id: 1, title: 'Купить хлеб', done: true },
    { id: 2, title: 'Позвонить Олегу', done: false },
  ]);
}
<!-- src/app/todo-list/todo-list.html -->
<ul>
  @for (todo of todos(); track todo.id) {
    <li><app-todo-item [title]="todo.title" /></li>
  }
</ul>

На странице два пункта: «Купить хлеб» и «Позвонить Олегу». Строку-константу можно передать без скобок: <app-todo-item title="Купить хлеб" />.

Обязательный вход

Компоненту задачи нужен весь объект, а не только заголовок. Без задачи компонент бессмыслен, поэтому вход делаем обязательным:

// src/app/todo-item/todo-item.ts
import { Component, input } from '@angular/core';
import { Todo } from '../todo';
 
@Component({
  selector: 'app-todo-item',
  templateUrl: './todo-item.html',
  styleUrl: './todo-item.css',
})
export class TodoItem {
  todo = input.required<Todo>();
}
<!-- src/app/todo-item/todo-item.html -->
<span [class.done]="todo().done">{{ todo().title }}</span>

В шаблоне родителя теперь пишут <app-todo-item [todo]="todo" />. Если забыть передать todo, сборка выдаст ошибку ещё до запуска.

Вычисления из входа

Входное свойство — сигнал, поэтому из него можно строить computed:

// src/app/todo-item/todo-item.ts
label = computed(() => (this.todo().done ? 'готово' : 'в работе'));

label() пересчитается сам, когда родитель передаст другую задачу. Не забудьте импортировать computed из @angular/core.

Частая ошибка

Пытаться изменить вход изнутри: this.todo.set(...). У входного свойства нет метода set — данными владеет родитель. Если дочерний компонент хочет что-то изменить, он сообщает об этом родителю через выход, о котором следующий урок.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.