Перейти к содержанию

Динамические компоненты

Динамические компоненты создаются уже в скомпилированном приложении в момент его работы.

В Angular динамическая компиляция компонентов реализована через сервис ComponentFactoryResolver.

Для отображения такого компонента сперва необходимо определить место, где он будет располагаться. Местом служит ссылка на представление типа ViewContainerRef.

books-list.component.html

1
2
3
4
5
6
7
<div>
    <div class="book-item" #book>
        <p>No books</p>
    </div>

    <button (click)="addBook()">Add book</button>
</div>

books-list.component.ts

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@Component({
    selector: 'books-list',
    templateUrl: './books-list.component.html',
})
export class AppComponent {
    @ViewChild('book') book;

    constructor(
        private componentFactoryResolver: ComponentFactoryResolver
    ) {}

    addBook() {
        this.book.viewContainerRef.clear();

        let bookItemComponent = this.componentFactoryResolver.resolveComponentFactory(
            BookItemComponent
        );
        let bookItemComponentRef = this.book.viewContainerRef.createComponent(
            bookItemComponent
        );
        (<BookItemComponent>(
            bookItemComponentRef.instance
        )).value = {
            title: 'Great Expectations',
            author: 'Charles Dickens',
        };
    }
}

book-item.component.html

1
2
3
4
<div class="book-item">
    <div>Title: {{value?.title}}</div>
    <div>Author: {{value?.author}}</div>
</div>

book-item.component.ts

1
2
3
4
5
6
7
8
@Component({
    selector: 'book-item',
    templateUrl: './book-item.component.html',
})
export class BookItemComponent {
    value: any = null;
    constructor() {}
}

Вызов метода clear() у viewContainerRef очищает содержимое блока представления.

Метод resolveComponentFactory() сервиса ComponentFactoryResolver принимает определение класса нужного динамического компонента и возвращает его экземпляр в виде ссылки типа ComponentRef. Для добавления созданного экземпляра в шаблон необходимо передать его в качестве параметра методу createComponent() экземпляра класса ViewContainerRef.

Метод createComponent() возвращает ссылку на созданный компонент, с помощью которой можно манипулировать значениями свойств компонента и вызывать его методы.

Все динамические компоненты (Angular dynamic component) должны перечисляться в свойстве entryComponents того модуля, к которому они относятся.

Стоит отметить, что невозможно создать компонент только в контроллере без представления. В шаблоне всегда должно быть предусмотрено для него место. Если не хочется плодить лишние HTML-теги — используйте Angular элемент <ng-template />.

1
2
3
4
5
<div>
    <button (click)="addBook()">Add book</button>

    <ng-template #book></ng-template>
</div>

Ссылки

Комментарии