Open IgorKulishov opened 5 years ago
От родителя к дочернему компоненту в принципе понятно. Но вот от дочернего к родителю.... никак не могу въехать, пытаясь разобраться, я запутываюсь еще сильнее. От этого начинаю беситься, и голова вообще отказывает... (( Я даже не могу толком сформулировать, что именно меня путает. Вообще, изначально, откуда все начинается? От selectedHero? Тогда почему он определяется в родительском компоненте, как и метод onSelectHero, а говорится, что передается из дочернего в родительский? selectHero и там, и там (и в родителе, и в дочернем). И там, и там с ним происходят изменения, поэтому я не могу понять, что первично, откуда начинается передача, с какого компонента, с какого момента делается 1й шаг, куда шагает операция дальше, и где это все заканчивается. В общем, у меня мозг закипает, не могу толком понять, от чего отталкиваться.
Прежде всего ни ты первый последний. Не даром говорят - "грызть гранит науки". Надо не забывать, что Angular это темплейтный язык и именно понимать его довольно сложно именно за счет добавленных темплейтных выражений (проще запоминать). Чувство когда трудно объяснить что не понятно мне тоже знакомо и как ни странно чаще возникает именно с Angular. Именно по этой причине программистам становиться сложно его осваивать, а тем более тем кто пришел с других языков им приходиться и работать и учиться осваивая находу. Именно за счет этого начинают набирать популярность другие фреймворки javascript vue.js, react.js
Тем не менее постараемся разобраться c Angular - думаю нам удасться разгрысть большую его часть - только надо набраться терпения немного и добавить практики (тут дело привычки, через какое-то время перестаешь спрашивать и все становиться привычным).
И так для начала я предлагаю посмотреть еще одно видео на русском языке https://www.youtube.com/watch?v=LV1x2X_QMVU.
А тем временем я подготовлю объяснение. Терпение и труд все перетрут! Удачи и терпения Бро! Все будет получаться, только надо время что бы разобраться и попрактироваться.
Далее я подготовлю объяснения по двум пунктам: 1) как выглядят вложеные компоненты (наглядно в режиме дебага на первой закладке : html) 2) как передаются события от дочерней компоненты к родительской при помощи EventEmitter (typescript) Напиши, если есть и другие вопросы.
1. как выглядят вложеные компоненты в html в режиме дебаг.
Если рассмотреть пример выше (2.А.) и гипотетически построить приложение и потом его рассмотреть в дебагере в первой закладке Elements
, то можно увидеть примерно следующую "матрешку" вложеных тэгов:
<parent-component *ngFor="let hero of heroes">
<child-component [hero]="hero" (selectedHero)="onSelectHero($event)">
<button (click)="selectHero()">{{hero.name}}
</button>
</child-component>
</parent-component>
Конечно же мы не увидем следующие элементы, поскольку они будут заменены на значения объектов определенных внутри ts кода внутри компоненты:
*ngFor="let hero of heroes"
{{hero.name}}
Так же мы не увидем:
"onSelectHero($event)"
Однако мы увидем самую последную матрешку, а именно html элементы дочерней компоненты
<button (click)="selectHero()">Winnie Pooh</button>
Примечание: {{hero.name}}
имя будет заменено значением из компоненты.
Таким образом мы видем что при нажатии на элемент <child-component>
, мы на самом деле будем кликать на <button (click)="selectHero()>
вызывая selectHero()
метод компоненты, который в свою очередь будет осуществлять вызов события методом emit (представителя класса EventEmitter о которых мы поговорим далее).
EventEmitter
это класс относящийся к RXJS библиотеке (Reactive library) мы будем подробно это проходить т.к. это активно используется в Angular.
Поскольку мы это не проходили, то мне будет немного сложно объяснить.
Скажу что это относится к библиотеке RXJS и это не совсем одно и тоже если сравнивать со стандартными HTML DOM javascript events.
Думаю тут пока надо будет только запомнить что для взаимодействия дочерней компоненты с родительской мы применяем EventEmitter.
Последовательность цепочки взаимодействия такая: дочерняя компонента посылает событие с объектом, сторой, номером или boolean при помощи метода emit класса EventEmitter родительской компоненте.
Родительская компоненты "слушает" событие и при получении события активирует метод определенный в аттрибутах родительской компоненты (п. 2.C.):
<child-component [hero]="hero" (selectedHero)="onSelectHero($event)"></child-component>
Вначале будет тяжеловато. Но думаю надо просто запомнить применение (не разбираясь как это работает) и потренироваться / поупражняться с Output пока это будет более менее привычно.
Тем временем дай знать когда можно будет переключиться на Reactive library. Думаю что это должно быть и в видео уроке (посмотрю позже). Эта тема встречается в service (сервисах) и этот принцип используется во-всех http REST calls (GET, POST, PUT, DELETE) там применяются названия Observables и subscribers . На Reactive можно переключиться всегда - не надо ждать завершения предыдущей главы. Не прощаюсь - удачи тебе Бро!
1. Рассмотрим передачу от родительской к дочерней компоненте:
A. Enclosed components structure/scheme:
This is how we pass simple object hero with only name property from Parent to Child component. Родительская компонента имеет несколько вложенных дочерних компонент (созданых с помощью циклического оператора
ngFor
). Дочерняя компонента принимает объектhero
через оператор[hero]=
, при этом значение родительского объекта справа от знака равенства внутри ковычек"hero"
.B. Parent component
Родительская компонента включает в
template:
дочернюю компоненту и показывает как будет происходить передача значения объектов от родительской к дочерней компоненте.C. Child component
Дочерняя компонента содержит:
hero
через который компонента получает значение родительского объекта при помощи оператора/декоратора@Input() hero
2. Рассмотрим передачу от дочерней к родительской компоненте:
A. Enclosed components structure/scheme:
Все тоже самое, только мы добавили
(selectedHero)="onSelectHero($event)"
для передачи объекта от дочерней к родительской компоненте. Дочерняя компонента передает объект через(selectedHero)
слева от знака равенства, при этом вызывается метод родительской компоненты и передается объект $event внутри метода"onSelectHero($event)"
.B. Parent component
Родительская компонента включает в
template:
дочернюю компоненту и показывает как будет происходить передача объекта от дочерней к родительской компоненте при помощи выражения (selectedHero)="onSelectHero($event)", где справа от знака равенства указывается метод родительской компоненты с параметром внутри скобок.C. Child component
Дочерняя компонента содержит:
@Output() selectedHero = new EventEmitter<{name: string;}>()
объект, через который будет происходить передача объекта через emitselectHero()
функция которая будет вызываться внутри темплейта при нажатии buttonselectHero()
@Input() hero
- как уже было показано выше в п.1.С.