Abr@X@bra.ru
Angular 2 компоненты: Inputs и Outputs
Angular 2 компоненты: Inputs и Outputs

Angular 2 компоненты: Inputs и Outputs

22.05.2017
2966
В этой статье мы подробнее рассмотрим компоненты - как они определены и как получить данные и от них отказаться. Тем не менее, мы не можем охватить все, что касается компонентов в одной статье, поэтому в будущих статьях будут рассмотрены другие аспекты Angular компонентов.

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

В частности, TypeScript поддерживает декораторы (иногда называемые «аннотации»), которые используются для декларативного добавления или изменения существующей «вещи». Например, декораторы классов могут добавлять метаданные к функции конструктора класса или даже изменять поведение класса. Для получения дополнительной информации о декораторах и типах вещей, которые вы можете с ними сделать, см. Предложение для декораторов JavaScript. Angular 2 включает в себя несколько декораторов.
Компоненты являются ключевым строительным инструментом для приложений Angular. Они включают в себя представление, определенное HTML и CSS, и связанный с ним контроллер, который реализует функциональность, необходимую для представления. Контроллер выполняет три основные функции:
  • Управление моделью, т. е. Данными приложения, используемыми представлением;
  • Внедрить методы, необходимые для представления таких вещей, как отправка данных или скрытие / показ разделов пользовательского интерфейса;
  • Управление данными, связанными с состоянием представления, таким как какой элемент в списке выбран.
Приведенный выше список может показаться знакомым. На самом деле контроллер Angular компонента очень похож на оригинальное определение модели представления, как это было определено Джоном Госсманом в 2005 году:

Этот термин означает «модель представления» может рассматриваться как абстракция представления, но он также предоставляет специализацию модели, которую может использовать представление для привязки данных. В этой последней роли ViewModel содержит преобразователи данных, которые преобразуют типы Model в типы View и содержат Commands, которые View может использовать для взаимодействия с Моделью.

Можете ознакомиться с данной статьей более подробно.

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

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

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

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


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

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

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

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


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

Inputs и Outputs

Давайте рассмотрим два свойства, которые можно передать декоратору @Component для реализации нисходящего и восходящего потока данных: «Inputs» и «Outputs». 

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



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

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



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

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

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

@Input () и @Output ()

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


Используем декоратор @Input и @Output

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

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

Вывод

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




Angular 2
Читайте также:
Псевдокласс Nth-child vs nth-of-type

Псевдокласс Nth-child vs nth-of-type

Селектора nth-child () и nth-of-type () являются «структурными псевдоклассами», которые позволяют нам вы...
Читать
Я все еще люблю jQuery - и вы тоже

Я все еще люблю jQuery - и вы тоже

В последнее время в JQuery широко используется стигма. Похоже, что все настойчиво избегают этого в современной разработк...
Читать
Протокол HTTPS или защита в интернете

Протокол HTTPS или защита в интернете

Путешествуя по интернету, кликая по ссылкам, запуская просмотр видеороликов, отправляя сообщение другу и или коллеге по ...
Читать