#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>
тоже.