В версии Angular 17.3 были представлены входы на основе сигналов в качестве реактивной альтернативы декоратору @Input().
Новые входы Angular предоставляют разработчикам новые возможности.
- Позволяют уже сегодня интегрировать и использовать преимущества сигналов Angular:
▹ более простые способы запуска логики при изменении входных данных;
▹ эффективные решения для получения состояния из входов;
▹ более плавное взаимодействие с OnPush
и будущим Zoneless.
- Обеспечивают повышение качества кода и производительности разработчиков за счет повышения безопасности типов вводимых данных.
Но как применить новый подход на практике? Из этой статьи вы узнаете, как использовать @model — особый тип ввода, который позволяет компонентам обмениваться новыми значениями.
Входы модели
Входы модели в настоящее время находятся в программе Developer Preview.
Представьте, что у вас есть приложение, в котором компонент списка или таблицы отделен от компонента фильтра, и они должны беспрепятственно взаимодействовать. Именно здесь директива @model
окажет неоценимую помощь, упрощая и облегчая двунаправленную привязку данных. Рассмотрим практический пример.
Для наглядности создадим приложение, которое отображает список студентов. Этот список можно динамически фильтровать по имени с помощью отдельного компонента фильтра. Полный код примера можно найти на GitHub, а рабочий пример — на StackBlitz.
Начнем с компонента student, где будут отображаться 2 атомарных компонента.
// student.component.html // Импортируется как "BANANA IN A BOX" (“банан в коробке”) <app-filter [(filterKeyword)]="keyword" /> <app-student-list [filterKeyword]="keyword()" /> // student.component.ts export class StudentComponent { keyword = signal(''); }
В компоненте student объявляем ключевое слово как signal. Оно будет передаваться между компонентами. Если понадобится передать данные в несколько мест, этого можно добиться, переместив const в сервис и беря его оттуда. Теперь перейдем к созданию другого компонента.
Компонент filter для фильтрации студентов по именам
Компонент filter — это простой компонент с объявлением модели и присвоением ей const
, чтобы можно было инициировать двунаправленную привязку.
// filter.component.ts export class FilterComponent { filterKeyword = model(''); }
Если вы инициируете модель без начального значения, рассмотрите возможность использования model.required
.
Чтобы просто инициировать привязку данных, присваивается const filterKeyword
:
<input [(ngModel)]="filterKeyword" />
Это позволит убедиться, что при каждом обновлении filterKeyword будет автоматически подставлять новое значение. Того же результата можно добиться, используя метод filterKeyword.update(() => 'updated value')
.
Извлечение реактивного значения с помощью computed()
Функция computed()
может быть использована для создания вычисляемого Signal
, который извлекает реактивное значение из выражения. В нашем случае используем этот метод для обновления списка при каждом изменении фильтра.
filteredStudents = computed(() =>
STUDENTS.filter((s) =>
s.name.toLocaleLowerCase().includes(this.filterKeyword())
)
);
Заключение
Внедрение в последней предварительной версии Angular входных данных на основе сигналов — это значительный шаг вперед в расширении возможностей двунаправленной привязки данных. Отказавшись от традиционных декораторов @Input() и @Output() и приняв директиву @model, разработчики могут добиться более эффективного и реактивного управления состоянием. Такой подход не только упрощает процесс обработки изменений входа, но и повышает безопасность типов и производительность разработчиков.
Пример компонентов со списком студентов и фильтром демонстрирует, насколько простым и интуитивно понятным может быть двунаправленная привязка данных с помощью новой директивы @model. Используя сигналы, разработчики могут легко управлять изменениями состояния компонентов и распространять их, что приводит к созданию более чистого и удобного кода.
Поскольку Angular продолжает развиваться, использование этих новых реактивных парадигм будет иметь решающее значение для разработчиков, стремящихся создавать надежные и производительные приложения. Директива @model и вычисляемые сигналы предоставляют мощные инструменты для создания отзывчивых и динамичных пользовательских интерфейсов, прокладывая путь к более плавной разработке и более эффективному управлению состоянием.
Чтобы подробнее изучить эту новую функцию, ознакомьтесь с полным кодом примера на GitHub и посмотрите его в действии на StackBlitz (демо).
Для тех, кому интересно, что означает название “BANANA IN A BOX” (“банан в коробке”):
[] = box (коробка);
() = banana (банан);
[()] = banana in a box (банан в коробке).
Читайте также:
- 8 полезных функций Angular, о которых стоит знать
- Angular: как с функцией inject() сэкономить 1000 строк кода
- Как использовать React в приложениях Angular
Читайте нас в Telegram, VK и Дзен
Перевод статьи Sunil Soundarapandian: Stop using “@Input” “@output” in Angular