如何在Angular Dialog添加数据后刷新Mat-Table
问题描述
我想在添加数据后刷新Mat-Table的条目,但使用Dialog模块时表格无法更新。我试过在Products组件里用ViewChild调用List组件,但还是不行;不用Dialog的时候Mat-Table能正常更新,用了就不行,怎么解决?
Create Component
export class CreateComponent extends BaseComponent implements OnInit { userAddressValidations: FormGroup; constructor(private formBuilder: FormBuilder,spiner: NgxSpinnerService, private productService: ProductService, private alertify: AlertifyService) { super(spiner) } ngOnInit(): void { this.userAddressValidations = this.formBuilder.group({ name: ['', [Validators.required, Validators.minLength(5), Validators.maxLength(50), Validators.pattern('^[a-zA-Z ]*$')]], stock: ['', [Validators.required],Validators.min(0)], price: ['', [Validators.required],Validators.min(0)], }); } @Output() createdProduct: EventEmitter<Create_Product> = new EventEmitter(); create(name: HTMLInputElement, stock: HTMLInputElement, price: HTMLInputElement) { this.showSpinner(SpinnerType.BallAtom); const create_product: Create_Product = new Create_Product(); create_product.name = name.value; create_product.stock = parseInt(stock.value); create_product.price = parseFloat(price.value); this.productService.create(create_product, () => { this.hideSpinner(SpinnerType.BallAtom); this.alertify.message("Ürün başarıyla eklenmiştir.", { dismissOthers: true, messageType: MessageType.Success, position: Position.TopRight }); this.createdProduct.emit(create_product); }, errorMessage => { this.alertify.message(errorMessage, { dismissOthers: true, messageType: MessageType.Error, position: Position.TopRight }); }); } }
Dialog Service
export class DialogService { constructor(private dialog: MatDialog) { } openDialog(dialogParameters: Partial<DialogParameters>): void { const dialogRef = this.dialog.open(dialogParameters.componentType, { width: dialogParameters.options?.width, height: dialogParameters.options?.height, position: dialogParameters.options?.position, data: dialogParameters.data, }); dialogRef.afterClosed().subscribe(result => { if (result == dialogParameters.data) dialogParameters.afterClosed(); }); } } export class DialogParameters { componentType: ComponentType<any>; data: any; afterClosed: () => void; options?: Partial<DialogOptions> = new DialogOptions(); } export class DialogOptions { width?: string = "250px"; height?: string; position?: DialogPosition; }
Products Component
export class ProductsComponent extends BaseComponent implements OnInit { constructor(spinner: NgxSpinnerService, private httpClientService: HttpClientService, private dialogService: DialogService,private dialog:MatDialog) { super(spinner) } createProduct() { this.dialogService.openDialog({ componentType: CreateComponent, data: null, options: { width: "500px" }, afterClosed: () => { } }, ); } ngOnInit(): void { } }
HTML 代码片段
<button style="margin:15px;font-size: 17px;text-align: center;align-content: center;" mat-raised-button class="btn" color="primary" (click)="createProduct()"> <!-- Products组件内的代码 --> @ViewChild(ListComponent) listComponents: ListComponent; createdProduct(createdProduct: Create_Product) { this.listComponents.getProducts(); console.log(this.listComponents); }
解决方案
核心问题是:Dialog动态创建的组件和原父组件(Products)不在同一组件树,@Output事件无法直接传递,导致刷新方法没被触发。以下是两种解决方式:
方式一:改造DialogService传递组件事件
更新DialogService,支持监听Dialog内组件的输出事件,把数据传递回调用方:
export class DialogService { constructor(private dialog: MatDialog) { } openDialog<T>(dialogParameters: Partial<DialogParameters<T>>): void { const dialogRef = this.dialog.open(dialogParameters.componentType, { width: dialogParameters.options?.width, height: dialogParameters.options?.height, position: dialogParameters.options?.position, data: dialogParameters.data, }); // 订阅Dialog内组件的指定输出事件 const componentInstance = dialogRef.componentInstance; if (dialogParameters.eventName && dialogParameters.onComponentEvent) { componentInstance[dialogParameters.eventName].subscribe((eventData: any) => { dialogParameters.onComponentEvent(eventData); }); } dialogRef.afterClosed().subscribe(result => { if (result == dialogParameters.data && dialogParameters.afterClosed) { dialogParameters.afterClosed(); } }); } } // 更新参数类,新增事件监听字段 export class DialogParameters<T> { componentType: ComponentType<any>; data: T; afterClosed?: () => void; options?: Partial<DialogOptions> = new DialogOptions(); eventName?: string; // 要监听的组件输出事件名 onComponentEvent?: (data: any) => void; // 事件回调 } export class DialogOptions { width?: string = "250px"; height?: string; position?: DialogPosition; }
然后修改Products组件的调用逻辑,绑定事件触发刷新:
export class ProductsComponent extends BaseComponent implements OnInit { @ViewChild(ListComponent) listComponents: ListComponent; constructor(spinner: NgxSpinnerService, private httpClientService: HttpClientService, private dialogService: DialogService,private dialog:MatDialog) { super(spinner) } createProduct() { this.dialogService.openDialog({ componentType: CreateComponent, data: null, options: { width: "500px" }, eventName: 'createdProduct', // 指定要监听的输出事件名 onComponentEvent: (createdProduct: Create_Product) => { this.createdProduct(createdProduct); // 触发刷新 }, afterClosed: () => { } }); } createdProduct(createdProduct: Create_Product) { this.listComponents.getProducts(); console.log(this.listComponents); } ngOnInit(): void { } }
方式二:简化逻辑,Dialog关闭后直接刷新
如果不需要传递创建的产品数据,可直接在Dialog关闭回调里触发表格刷新,无需处理事件传递:
createProduct() { this.dialogService.openDialog({ componentType: CreateComponent, data: null, options: { width: "500px" }, afterClosed: () => { // 对话框关闭后直接调用刷新方法 this.listComponents.getProducts(); } }); }
内容的提问来源于stack exchange,提问作者Mustafasan
相关产品推荐
相关产品推荐

