
Angular: как получить доступ к компоненту внутри ‹ng-content› с помощью @ContentChild
При создании компонентов в Angular иногда нам нужно поместить один компонент внутрь другого. Для этого мы можем либо объявить компонент в шаблоне другого компонента, либо использовать проекцию контента и поместить компонент внутри тегов другого компонента. В этой статье я покажу вам, как родительский компонент может получить доступ к свойствам компонента, размещенного с помощью проекции содержимого.
1. Создайте новый проект
Во-первых, давайте создадим новый проект. Если вы не знаете, как это сделать, рекомендую мою статью, где вы найдете инструкцию как создать новый проект в Angular.
2. Создайте CarDescriptionComponent
Давайте создадим компонент CarDescription, используя следующую команду:
ng g c car-description
В этом компоненте мы объявим две переменные: «description», в которой будет храниться описание автомобиля, и «price», в которой будет храниться его цена. Код компонента ниже:
import { Component } from '@angular/core';
@Component({
selector: 'app-car-description',
template: `<p>{{description}}</p>`,
styleUrls: ['./car-description.component.css']
})
export class CarDescriptionComponent {
description: string = 'This car will provide you with an amazing experience, and its performance will ensure that you will never want to drive anything else.';
price: number = 10000;
}
3. Создайте автомобильный компонент
Теперь давайте создадим CarComponent с помощью следующей команды:
ng g c car
Затем введите код ниже:
import { ContentChild } from '@angular/core';
import { AfterViewInit } from '@angular/core';
import { Component } from '@angular/core';
import { CarDescriptionComponent } from '../car-description/car-description.component';
@Component({
selector: 'app-car',
template: `<h1>Ford Mustang</h1>
<ng-content select="[description]"></ng-content>`,
styleUrls: ['./car.component.css']
})
export class CarComponent implements AfterViewInit { }
В этом компоненте мы разместили тег ‹ng-content›, благодаря которому можно будет проецировать контент. Содержимое будет отображаться только в том случае, если компонент, который мы хотим поместить внутрь, будет помечен директивой «описание». Это условие указано в директиве select.
4. Показать компоненты
Чтобы увидеть, как работает наше простое приложение, вставьте приведенный ниже код в файл app.component.html:
<app-car> <app-car-description></app-car-description> </app-car>
Компонент app-car-description будет помещен внутри тегов ‹ng-content› в CarComponent благодаря директиве «description». После запуска мы должны получить такой вид:
5. Используйте @ContentChild
Если мы хотим не только отобразить компонент, но и получить доступ к его переменным, пригодится атрибут @ContentChild, который позволяет получить доступ к переменным, содержащимся в компоненте, размещенном внутри ‹ng-content›. В файл car.component.ts поместите следующий код:
export class CarComponent implements AfterViewInit {
@ContentChild(CarDescriptionComponent) carDescription: CarDescriptionComponent
ngAfterViewInit() {
console.log(this.carDescription);
const price = this.carDescription.price;
console.log('price from carDescription: ', price);
}
Когда мы открываем консоль браузера, мы должны увидеть это:
Как видите, благодаря декоратору @ContentChild мы получили доступ к переменным внутри CarDescriptionComponent. При использовании @ContentChild важно добраться до компонента после его инициализации — для этого я использовал хук «ngAfterViewInit()». Если мы сошлемся на этот компонент перед его инициализацией, например, с помощью «ngOnInit()», мы получим «undefined». Если мы хотим получить доступ к компоненту в «ngOnInit()», мы должны использовать «static: true», как показано ниже:
@ContentChild(CarDescriptionComponent, { static: true}) carDescription: CarDescriptionComponent
Краткое содержание
Благодаря атрибуту @ContentChild мы можем получить доступ к переменным в компоненте, который хотим поместить внутрь ‹ng-content›. Однако не забывайте использовать правильный хук.