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

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

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

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

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

books-list.component.html

<div>
  <div class="book-item" #book>
    <p>No books</p>
  </div>

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

books-list.component.ts

@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

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

book-item.component.ts

@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 />.

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

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

Ссылки