Через интерполяцию добавляем эту перенную в наш шаблон:
<div class="card">
<h2>{{ title }}</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Adipisci, ratione.</p>
</div>
Интерполировать можно все, что можно привести к строке — любые простые типы. Если мы попробуем проинтерполировать объект, то мы получим [object Object]. Чтобы все таки увидеть содержимое объекта можно использовать такую штуку как пайпы. Например, конвертнем объект в json:
Это механизм связки компонента и шаблона, который присутствует в Angular. Позволяет в одностороннем порядке связывать данные (изменилось что-то в компоненте — изменилось во view).
Допустим, мы хотим менять динамически какой-то элемент шаблона (например, картинку).
Это сработает, но такой синтаксис не совсем корректен. Для этого есть механизм binding.
Делается это через оборачивание атрибута в квадратные скобки:
<div>
<img [src]="imgUrl">
</div>
Соотв, Angualr понимает, что в значении атрибута будет код TS (или JS).
Event binding (Two Way Binding)
Делается это через оборачивания события в круглые скобки и прописывания обработчика:
<div class="card">
<h2>{{ title }}</h2>
<p>{{ testText }}</p>
<div>
<button (click)="changeTitle()">Change Title</button>
<button (click)="title = 'Inline title'">Change Title Inline</button>
</div>
<div>
<!-- $event — это нативный ивент, нужен для обработчика -->
<input type="text" (input)="inputHandler($event)" [value]="title">
<!-- Другой вариант (более простой) — через локальную ссылку на элемент -->
<input type="text" #myInput (input)="inputHandler2(myInput.value)" [value]="title">
</div>
</div>
В angular есть встроенный модуль, который позволяет это реализовать еще проще. Для этого в нашем модуле, в поле imports мы должны подключить еще один базовый модуль — FormsModule:
Модуль FormsModule содержит в себе функциональность, которая позволяет работать с формами, и содержит в себе ngModel, который позволяет добавлять механизм Two Way Binding гораздо проще (мы просто оборачиваем и квадратные и в круглые скобки ngModel и в значение помещаем то поле, которое хотим связать в двустороннем порядке):
<div class="card">
<h2>{{ title }}</h2>
<p>{{ testText }}</p>
<div>
<!-- 2way binding через FormsModule -->
<input type="text" [(ngModel)]="title">
<!-- Так же, дополнительно есть событие для подписи на изменение поля -->
<input type="text" [(ngModel)]="title" (ngModelChange)="changeHandler()">
</div>
</div>
Pass data between parent and child components
Parent -> Child ( @Input() )
Делается это путем объявления поля через декоратор @Input().
exportclassSomeParentComponent {onNotify(value:boolean) {// some actions }}
Calls functions to other components
Calls child's functions from the parent component
Делается через именование компонента — #childComponent. Пример:
<div class="card">
<h2>{{ title }}</h2>
<p>{{ testText }}</p>
<div>
<button (click)="changeTitle(childComponent.value)">Change Title</button>
</div>
<div>
<!-- Другой вариант (более простой) — через локальную ссылку на элемент -->
<input type="text" #childComponent (input)="inputHandler2(childComponent.value)" [value]="title">
</div>
</div>
Другой способ (более гибкий) — инжектить дочерний компонент внутрь родительского через @ViewChild. Пример:
import { AfterViewInit, ViewChild } from'@angular/core';import { Component } from'@angular/core';import { ChildComponent } from'./child';@Component({..., tempate:` <div class="seconds">{{ seconds() }}</div> <app-child></app-child> `,...})exportclassParentComponentimplementsAfterViewInit { @ViewChild(ChildComponent)private childComponent!:ChildComponent;seconds() {return0;}ngAfterViewInit() {// Redefine `seconds()` to get from the `ChildComponent.seconds` ...// but wait a tick first to avoid one-time devMode// unidirectional-data-flow-violation error// Кратко: это хак, тк дочерний компонент не существует, пока не отрисуется родительский,// а следовательно, вызов функций невозможен ( child.seconds() ).// Этот код дожидается 1 тик времени, прежде чем переопределить функциюsetTimeout(() =>this.seconds= () =>this.childComponent.seconds,0); }start() { this.childComponent.start(); }}
Отписка от событий в ngOnDestroy() крайне важна для дочерних элементов, тк это защищает от утечек памяти (для родительских компонентов этого делать не надо, тк сервис SomeService закрывается вместе с родительским компонентом).