Повторное использование существующего компонента Angular в диалоговом окне material

#angular #dialog #angular-material

#angular #диалоговое окно #angular-материал

Вопрос:

У меня есть существующий компонент, ResultGridComponent которому передаются данные @Input() . Я хочу использовать тот же компонент для MatDialog . Следовательно, я добавил @Inject(MAT_DIALOG_DATA) data в конструктор ResultGridComponent компонента.

 constructor(private spinner: EdpLoaderService, private dialog: MatDialog, @Optional() @Inject(MAT_DIALOG_DATA) data) {}
  

Но когда компонент вызывается в соответствии с его обычным использованием, то есть не как диалоговое окно, я получаю следующую ошибку :

ОШИБКА Ошибка: StaticInjectorError (AppModule)[ResultGridComponent -> InjectionToken MatDialogData]: StaticInjectorError (Платформа: ядро) [ResultGridComponent -> InjectionToken MatDialogData]: NullInjectorError: нет поставщика для InjectionToken MatDialogData!

Я почти уверен, что импортировал все необходимые модули. Потому что я создал отдельный компонент для диалогового окна и передал в него данные, и это сработало нормально. Но я хочу повторно использовать компонент. И я почти уверен, что эта ошибка возникает, когда я вызываю конструктор MatDialogData дочернего компонента как обычный компонент, и конструктор не получает,,, переданный ему вызывающим.

Комментарии:

1. Привет, Сатвир, как ты решил эту проблему? У меня точно такая же проблема, и решение @Stan у меня не работает.

Ответ №1:

В некоторых случаях я бы использовал @Optional() перед @Inject(MAT_DIALOG_DATA).

   constructor(
    @Optional() @Inject(MAT_DIALOG_DATA) dialogData: any
  ) {
    if (dialogData) {
     // here pass dialog data to the child component
    }
  }
  

Ответ №2:

Я смог найти решение ситуации.


Постановка проблемы: Я пытался использовать существующий компонент (назовем его дочерним компонентом) в двух разных местах. Один как обычный дочерний компонент, а второй как компонент внутри диалогового окна Material.


Задача: Чтобы передать данные компоненту dialog, нам нужно @Inject(MAT_DIALOG_DATA) в дочернем компоненте. Но когда вы вводите дочерний компонент внутри обычного компонента, вы не предоставляете никакого поставщика для ‘@Inject(MAT_DIALOG_DATA)’. Следовательно, при инициализации происходит сбой. И нам действительно нужен ‘@Inject(MAT_DIALOG_DATA)’, если мы хотим использовать дочерний компонент внутри диалогового окна Mat.


Решение: Создайте компонент-оболочку, назовем его (ChildWrapperComponent). Для обычного варианта использования непосредственно внедрите дочерний компонент в родительский компонент. Принимая во внимание, что для варианта использования диалогового окна Mat необходимо предоставить ChildWrapperComponent

 const dialogRef  = this.dialog.open(ChildWrapperComponent, {
                 width: '90%',
                 disableClose: false,
                 data: {
                   fileName: this.fileName,
                   results: this.results
                 }
               } );
  

Теперь вы можете хранить данные внутри дочернего компонента, используя данные @Inject(MAT_DIALOG_DATA)

 constructor(private spinner: EdpLoaderService, private dialog: MatDialog,
@Inject(MAT_DIALOG_DATA) data,
private dialogRef: MatDialogRef<ChildWrapperComponent>) {
this.setInputData(data);
  

}

Как только у вас появятся данные внутри дочернего компонента, вставьте дочерний компонент внутрь оболочки и передайте данные с помощью @Input().

Я новичок в Angular. Был бы очень признателен за лучшие или другие решения.

Ответ №3:

Я решил это, добавив поставщиков, подобных этому, после прочтения dependency-injection-providers

 @Component({
  ...
  ...
  providers: [
    { provide: MatDialogRef, useValue: this },
  ]
})
  

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

Ответ №4:

Столкнулся с ошибкой

 ERROR Error: Uncaught (in promise): NullInjectorError: R3InjectorError(n)[InjectionToken MatDialogData -> InjectionToken MatDialogData -> InjectionToken MatDialogData]:
  NullInjectorError: No provider for InjectionToken MatDialogData!
  

Решается путем добавления @Optional decorator перед @Inject(MAT_DIALOG_DATA) в конструкторе компонента

 constructor ( @Optional() @Inject(MAT_DIALOG_DATA) public dialogData: any ) { }
  

При использовании MatDialogRef добавьте @Optional() перед MatDialogRef<SomeComponent> тоже.