Angular - модальный материал с оберткой компонента и компонентом в качестве параметра - PullRequest
0 голосов
/ 07 мая 2020

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

  open(component: any | TemplateRef<any>, params, viewMode: ViewMode = ViewMode.EDIT, className: string[] = ['as-dialog', 'as-dialog-large']): Observable<any> {

// Here some way to nest component in AsDialogWrapperComponent
// and then displaying AsDialogWrapperComponent with nested component as content
    this.dialogRef = this.matDialog.open(AsDialogWrapperComponent, {
      data: {
        params,
        viewMode
      },
      panelClass: className
    });
    return this.dialogRef.afterClosed();
  }

Код оболочки будет:

<div class="as-box as-vertical as-fh">
  <div class="as-dialog-header">
    <p class="as-dialog-header-text" mat-dialog-title #title></p>
  </div>
  <mat-dialog-content #content></mat-dialog-content>
</div>

Поэтому мне интересно, есть ли способ вложить компонент, который входит в качестве параметра. Я пытался что-то сделать с componentFactoryResolver, но так и не понял.

Причина всего в том, что некоторые представления могут быть как модальными, так и полноэкранными. Поэтому я мог бы использовать модальную оболочку, которая будет принимать заголовок как параметр, а некоторые модальные действия - как параметр или настраиваемую панель кнопок.

Спасибо за любые советы.

1 Ответ

0 голосов
/ 07 мая 2020

Почему бы не получить данные для вашего компонента из службы, чтобы вам не нужно было передавать их через токен внедрения MAT_DIALOG_DATA, а затем вы могли бы использовать свой компонент либо в полноэкранном режиме, либо в диалоговом режиме без необходимости использования оболочки. Убедитесь, что вы добавили его в список entryComponents вашего модуля, хотя

В противном случае ответ на ваш вопрос может быть таким: В диалоговом окне оболочки «AsDialogWrapperComponent»:

  private createComponent(config: DialogConfig) {
    this.destroyComponent();
    const factory: ComponentFactory<DialogBase<any>> = this.resolver.resolveComponentFactory(config.component);
    this.componentRef = this.container.createComponent(factory);
    (this.componentRef.instance as DialogBase<any>).data = config.data;
    (this.componentRef.instance as DialogBase<any>).close
      .pipe(take(1))
      .subscribe(this.closeDialog.bind(this));
    this.cdRef.detectChanges();
  }

  private destroyComponent() {
    this.container.clear();
    if (this.componentRef) {
      this.componentRef.destroy();
      this.componentRef = null;
    }
  }

где вводится конфигурация в диалоговом окне оболочки:

constructor(@Inject(MAT_DIALOG_DATA) public data: DialogConfig) {}

и это выглядит так:

export interface DialogConfig {
  component: { new(...args: any[]): any; };
  data: any;
}

и DialogBase может быть классом, который расширяет ваш внутренний компонент:

import {
  EventEmitter,
  Output
} from '@angular/core';

export class DialogBase<T> {

  @Output() close: EventEmitter<void> = new EventEmitter();

  private _data: T;

  constructor() {
  }

  set data(data: T) {
    this._data = data;
  }

  get data(): T {
    return this._data;
  }
}

и T, интерфейс данных, ожидаемый вашим компонентом:

export class EditDialogComponent extends DialogBase<EditDialogData> {
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...