英文:
Trouble creating a reusable Angular Material dialog wrapper component
问题
我正在尝试创建一个可重用的Angular组件,它充当Material Angular对话框的包装器。目标是将子组件或模板传递给包装器组件,然后使用MatDialog服务打开它。
我已经创建了一个DialogWrapperComponent,它使用@ContentChild接受一个子组件。然而,当我尝试将子组件传递给MatDialog.open()方法时,我遇到了问题,对话框没有如预期般打开。
这是我的DialogWrapperComponent模板的示例:
<!-- dialog-wrapper.component.html -->
<ng-container #templateRef>
<ng-content></ng-content>
</ng-container>
这是我在父组件中如何使用DialogWrapperComponent的简化版本示例:
<!-- app.component.html -->
<app-dialog-wrapper>
<mat-dialog-content>
<!-- 内容放在这里 -->
</mat-dialog-content>
</app-dialog-wrapper>
在我的父组件中,我正在使用DialogWrapperComponent,并尝试将mat-dialog-content作为要在对话框中显示的子组件传递。
我不确定我漏掉了什么,或者是否有更好的方法来实现我的目标,即创建一个可重用的Material Angular对话框包装器组件。是否有人可以提供指导或建议一个有效的解决方案来创建一个可重用的Material Angular对话框包装器组件?
英文:
I'm trying to create a reusable Angular component that acts as a wrapper for Material Angular dialogs. The goal is to pass a child component or template to the wrapper component and then open it using the MatDialog service.
I've created a DialogWrapperComponent that accepts a child component using @ContentChild. However, when I attempt to pass the child component to the MatDialog.open() method, I encounter issues and the dialog does not open as expected.
Here's an example of my DialogWrapperComponent template:
<!-- dialog-wrapper.component.html -->
<ng-container #templateRef>
<ng-content></ng-content>
</ng-container>
And here's a simplified version of how I'm using the DialogWrapperComponent in my parent component:
<!-- app.component.html -->
<app-dialog-wrapper>
<mat-dialog-content>
<!-- Content goes here -->
</mat-dialog-content>
</app-dialog-wrapper>
In my parent component, I'm using the DialogWrapperComponent and trying to pass the mat-dialog-content as the child component to be displayed in the dialog.
I'm not sure what I'm missing or if there's a better approach to achieve my goal of creating a reusable dialog wrapper component. Can anyone provide guidance or suggest an effective solution for creating a reusable Material Angular dialog wrapper component?
答案1
得分: 0
由于MatDialog的工作方式,它要求传递一个组件(Component)或模板引用(TemplateRef)。当前,您正在传递一个DOM元素以创建对话框,因此它无法正常工作。
您可以按照以下方式为MatDialog
创建可重用的模板。
首先,创建一个包含您想要重用的模板的组件。假设这是一个确认对话框:
<!-- app-confirmation-dialog.html -->
<h2 mat-dialog-title>Delete Confirmation</h2>
<mat-dialog-content>
Are you sure you want to delete this item?
</mat-dialog-content>
<mat-dialog-actions>
<button mat-button mat-dialog-close>Cancel</button>
<button mat-button [mat-dialog-close]="true">Delete</button>
</mat-dialog-actions>
然后,您可以创建一个服务,在您想要删除项目时打开此ConfirmationDialogComponent。因此,这个服务变得可重用:
// dialog.service.ts
import { Injectable } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { ConfirmationDialogComponent } from './dialogs/confirmation-dialog.component';
@Injectable({ providedIn: 'root' })
export class DialogService {
constructor(private dialog: MatDialog) { }
openConfirmDialog() {
return this.dialog.open(ConfirmationDialogComponent, {
width: '390px',
panelClass: 'confirm-dialog-container',
disableClose: true
});
}
}
在您的组件中,您将如下使用这个服务:
// app.component.ts
import { Component } from '@angular/core';
import { DialogService } from '../services/dialog.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
})
export class AppComponent {
constructor(private dialogService: DialogService) {}
deleteItem() {
const dialogRef = this.dialogService.openConfirmDialog();
dialogRef.afterClosed().subscribe(res => {
if (res) {
// 用户点击了 'Delete'
} else {
// 用户点击了 'Cancel' 或关闭了对话框
}
});
}
}
您可以为所有的对话框模板重复使用这个模式,只需调整传递给open()
方法的组件即可。
英文:
Actually, due to the way MatDialog works, it requires passing a Component or a TemplateRef to it. Right now, you are passing a DOM element to create a dialog. Hence it's not working.
You can create reusable templates for a MatDialog
the following way.
First, create a component that includes a template you want to reuse. Say it's a confirmation dialog:
<!-- app-confirmation-dialog.html -->
<h2 mat-dialog-title>Delete Confirmation</h2>
<mat-dialog-content>
Are you sure you want to delete this item?
</mat-dialog-content>
<mat-dialog-actions>
<button mat-button mat-dialog-close>Cancel</button>
<button mat-button [mat-dialog-close]="true">Delete</button>
</mat-dialog-actions>
Then, you can create a service that opens this ConfirmationDialogComponent when you want to delete an item. This service therefore becomes reusable:
// dialog.service.ts
import { Injectable } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { ConfirmationDialogComponent } from './dialogs/confirmation-dialog.component';
@Injectable({ providedIn: 'root' })
export class DialogService {
constructor(private dialog: MatDialog) { }
openConfirmDialog() {
return this.dialog.open(ConfirmationDialogComponent, {
width: '390px',
panelClass: 'confirm-dialog-container',
disableClose: true
});
}
}
In your component you will use this service as follows:
// app.component.ts
import { Component } from '@angular/core';
import { DialogService } from '../services/dialog.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
})
export class AppComponent {
constructor(private dialogService: DialogService) {}
deleteItem() {
const dialogRef = this.dialogService.openConfirmDialog();
dialogRef.afterClosed().subscribe(res => {
if (res) {
// User clicked 'Delete'
} else {
// User clicked 'Cancel' or closed the dialog
}
});
}
}
You can reuse this pattern for all your dialog templates, just adjust the component you pass into the open()
method.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论