Статьи

Угловые 2 компонента: входы и выходы

В этой статье мы немного подробнее рассмотрим компоненты Angular 2 — как они определены и как вводить данные в них и возвращаться из них.

Это вторая часть серии Angular 2. Вы можете прочитать первую часть здесь . Мы рассмотрели основную идею компонентов и декораторов в предыдущей статье и конкретно увидели декораторы @Component и @View используемые для создания приложения Angular. Эта статья погружается немного глубже. Однако мы не можем охватить все о компонентах в одной статье, поэтому в будущих статьях будут рассмотрены другие аспекты компонентов Angular 2.

Код для этой статьи и других статей серии доступен как в репозитории angular2-samples . Вы также можете увидеть образцы, запущенные по адресу: http://angular2-samples.azurewebsites.net/ .

Хотя можно писать приложения на Angular 2 на ECMAScript 5 (наиболее распространенная версия JavaScript, поддерживаемая браузерами), мы предпочитаем писать на TypeScript . Сам Angular 2 написан на TypeScript, и он помогает нам во время разработки и включает в себя функции, которые облегчают нам определение компонентов Angular 2.

В частности, TypeScript поддерживает декораторы (иногда называемые «аннотациями»), которые используются для декларативного добавления или изменения существующей «вещи». Например, декораторы класса могут добавлять метаданные в функцию-конструктор класса или даже изменять поведение класса. Для получения дополнительной информации о декораторах и типах вещей, которые вы можете с ними делать, см. Предложение для декораторов JavaScript . Angular 2 включает в себя несколько декораторов.

Как мы уже упоминали в предыдущей статье, компоненты Angular 2 являются ключевым строительным блоком для приложений Angular. Они включают в себя представление, определенное с помощью HTML и CSS, и связанный контроллер, который реализует функциональные возможности, необходимые представлению. Контролер имеет три основных обязанности:

  • Управление моделью, т. Е. Данные приложения, используемые представлением
  • Реализуйте методы, необходимые представлению для таких вещей, как отправка данных или скрытие / отображение разделов пользовательского интерфейса.
  • Управление данными, относящимися к состоянию представления, например, какой элемент в списке выбран в данный момент.

В зависимости от вашего фона приведенный выше список может показаться знакомым. Фактически, контроллер компонента Angular очень похож на первоначальное определение модели представления, определенное Джоном Госсманом в 2005 году:

Термин означает «модель представления» и может рассматриваться как абстракция представления, но он также обеспечивает специализацию модели, которую представление может использовать для привязки данных. В этой последней роли ViewModel содержит преобразователи данных, которые преобразуют типы моделей в типы представлений, и содержит команды, которые представление может использовать для взаимодействия с моделью. Источник (захвачено 27.11.2015)

Поскольку компоненты Angular 2 не являются нативными объектами JavaScript, Angular предоставляет способ определения компонента путем сопряжения функции конструктора с представлением. Вы делаете это, определяя функцию конструктора (в TypeScript она определяется как класс) и используя декоратор, чтобы связать ваше представление с конструктором. Декоратор также может установить различные параметры конфигурации для компонента. Эта магия достигается с @Component декоратора @Component мы видели в первой статье этой серии.

Иерархия компонентов

Выше описан отдельный компонент, но приложения Angular 2 фактически состоят из иерархии компонентов — они начинаются с корневого компонента, который содержит в качестве потомков все компоненты, используемые в приложении. Компоненты Angular 2 должны быть автономными, потому что мы хотим инкапсулировать функции наших компонентов, и мы не хотим, чтобы другой код произвольно доходил до наших компонентов для чтения или изменения свойств. Кроме того, мы не хотим, чтобы наш компонент влиял на другой компонент, написанный кем-то другим. Очевидным примером является CSS: если мы устанавливаем CSS для одного компонента, мы не хотим, чтобы наш CSS «сливался» с другими компонентами, так же как мы не хотим, чтобы другой CSS «сливался» с нашим компонентом.

В то же время компоненты должны обмениваться данными. Компоненты Angular 2 могут получать данные от своего родителя, если принимающий компонент специально заявил, что готов получать данные. Аналогично, компоненты могут отправлять данные своим родителям, вызывая событие, которое слушает родитель. Давайте посмотрим, как ведет себя иерархия компонентов. Для начала мы можем нарисовать его следующим образом:

Angular 2 компонента: поведение иерархии компонентов

Каждый блок является компонентом, и технически это представление называется «граф» — структура данных, состоящая из узлов и соединяющих «ребра». Стрелки представляют поток данных от одного компонента к другому, и мы видим, что данные передаются только в одном направлении. — сверху вниз до потомков. Кроме того, обратите внимание, что нет путей, которые позволили бы вам перемещаться от одного узла через другие узлы и обратно к тому, с которого вы начали. Официальное название для такой структуры данных — «ориентированный ациклический граф», то есть он течет только в одном направлении и не имеет круговых путей.

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

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

Это прекрасно работает для простого отображения данных, но в реальном мире данные должны будут проходить в другом направлении — резервное копирование иерархии — например, когда пользователь редактирует строку. В этом случае строка должна сообщить компоненту таблицы, что данные для строки изменились, чтобы изменение можно было отправить обратно на сервер. Проблема заключается в том, что, как показано выше, данные передаются только по иерархии, а не обратно. Чтобы обеспечить простоту одностороннего потока данных по иерархии, Angular 2 использует другой механизм для отправки данных обратно по иерархии: события.

Компоненты Angular 2: односторонний поток данных по иерархии

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

Угловые 2 компонента: входы и выходы

На этом высокоуровневом взгляде на компоненты Angular 2 под нашим поясом давайте рассмотрим два свойства, которые можно @Component декоратору @Component для реализации нисходящего и восходящего потока данных: «входы» и «выходы». Иногда они сбивает с толку, потому что в более ранней версии альфа-версии Angular 2 их называли «свойствами» (для «входных данных») и «событиями» (для «выходных данных»), и некоторые разработчики были не в восторге от изменения имени, хотя, похоже, это действительно так чтобы иметь смысл: https://github.com/angular/angular/pull/4435 .

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

Компоненты Angular 2: Использование свойств входов и выходов в декораторе @Component

Рисунок 1: Компонент, который использует свойства «input» и « @Component декораторе @Component

Есть несколько вещей, которые следует отметить в отношении входов и выходов выше:

  • Свойство «input», передаваемое декоратору @Components перечисляет «myname» как свойство компонента, которое может принимать данные. Мы также объявляем «myname» как открытое свойство в классе ParentComp . Если вы не объявите это, компилятор TypeScript может выдать предупреждение.
  • Свойство «output» выводит список «myevent» как пользовательское событие, которое ParentComp может выдать, которое сможет получить его родитель. В классе ParentComp «myevent» объявляется как и устанавливается как EventEmitter . EventEmitter — это встроенный класс, который поставляется с Angular, который предоставляет нам методы для управления и запуска пользовательских событий. Обратите внимание, что нам пришлось добавить EventEmitter в оператор импорта в верхней части файла.
  • Этот компонент отображает входящее «myname» в представлении, но когда мы пытаемся получить к нему доступ в конструкторе ParentComp оно еще не определено. Это связано с тем, что входные свойства недоступны, пока представление не будет отображено, что происходит после запуска функции конструктора.
  • Мы добавили обработчик события «click» в наш шаблон, который вызывает метод myeventEventEmitter « next() » и передает ему данные, которые мы хотим отправить вместе с событием. Это стандартный шаблон для отправки данных вверх по иерархии компонентов — использование «EventEmitter» для вызова метода « next() ».

Теперь, когда мы рассмотрели, как определить «входы» и «выходы» в компоненте, давайте посмотрим, как их использовать. Шаблон для компонента CompDemo использует компонент ParentComp:

Компоненты Anglular 2: Использование входных и выходных данных, определенных ParentComp

Рисунок 2: Этот компонент использует ввод и вывод, определенные ParentComp

Синтаксис довольно прост для использования «ParentComp»:

  • [myname] = "myFriend" : это говорит Angular, чтобы установить для входного свойства ParentComp «myname» значение «myFriend», интерполированное как свойство CompDemo. Обратите внимание, мы установили «myFriend» в конструкторе
  • (myevent) = "handleMyEvent($event)" : это указывает Angular на вызов handleMyEvent($event) CompDemo « handleMyEvent($event) », когда ParentComp запускает «myevent». Данные, которые мы передали методу « next() » в ParentComp, доступно в CompDemo путем передачи « $event » в качестве аргумента handleMyEvent() .

В обоих случаях левая сторона атрибута ссылается на что-то в ParentComp (свойство ввода или событие вывода), а правая часть ссылается на что-то, что интерпретируется в контексте CompDemo (свойство экземпляра или метод).

Если вы попытаетесь установить свойство в ParentComp без указания его в качестве входного свойства, Angular не выдаст ошибку, но также не установит свойство. Приведенный выше шаблон — передача данных через свойство «input» и отправка данных через событие «output» — является основным способом обмена данными между компонентами Angular 2. В следующей статье мы увидим, что мы также можем обмениваться данными между компонентами, определяя сервисы, которые можно внедрять в компоненты, эффективно давая нам возможность обмениваться данными или функциями между компонентами.

@Input () и @Output ()

Существует альтернативный синтаксис для определения входных свойств и выходных событий в компоненте. В приведенном выше примере мы использовали свойства входов и выходов объекта, переданного в декоратор @Component . Angular также позволяет нам использовать декоратор @Input и @Output чтобы получить тот же результат:

Компоненты Angular 2: Использование декораторов @Input и @Output
Рисунок 3: Использует декоратор @Input и @Output

В вышеприведенной версии ParentComp мы @Component свойств «входов» и «выходов» объекта определения @Component . Вместо этого мы добавили «Input» и «Output» к команде import в строке 2 и использовали декоратор @Input и @Output в классе @Output для объявления «myname» и «myevent».

Независимо от того, используете ли вы входы / выходы или @Input / @Output , результат один и тот же, поэтому выбор того, какой из них использовать, во многом является стилистическим решением.

Заворачивать

В этой статье мы более подробно рассмотрели компоненты Angular 2, их взаимосвязь, способ передачи данных в них и способы их возврата. Мы все еще царапаем поверхность с точки зрения компонентов; они, возможно, главная особенность Angular 2 и участвуют во всех аспектах проектирования и создания приложений Angular 2. В следующих статьях мы продолжим изучение компонентов Angular 2, более подробно рассмотрев службы Angular как способ повторного использования кода и инкапсуляции ключевых функций.

Больше практической работы с веб-разработкой

Эта статья является частью серии веб-разработки от Microsoft и DevelopIntelligence, посвященной практическому изучению JavaScript, проектам с открытым исходным кодом и рекомендациям по взаимодействию, включая браузер Microsoft Edge и новый механизм рендеринга EdgeHTML .

DevelopIntelligence предлагает обучение JavaScript под руководством инструктора , AngularJS Training и другие тренинги по веб-разработке для технических групп и организаций.

Мы рекомендуем вам протестировать браузеры и устройства, включая Microsoft Edge — браузер по умолчанию для Windows 10 — с бесплатными инструментами на dev.microsoftedge.com :

Более глубокое обучение у наших инженеров и евангелистов:

Наше сообщество проектов с открытым исходным кодом:

  • vorlon.JS (удаленное тестирование JavaScript между устройствами)
  • manifoldJS (развертывание кросс-платформенных веб-приложений)
  • babylonJS (3D-графика стала проще)

Больше бесплатных инструментов и материалов для веб-разработчиков:


Эта статья является частью серии веб-разработки от Microsoft. Спасибо за поддержку партнеров, которые делают возможным использование SitePoint.