You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 17:37:13