Angular 7调用ngOnInit方法或组件包含的任何其他方法

时间:2019-05-21 14:41:40

标签: javascript angular typescript angular7

在这种情况下,我有一个名为user-table-list的组件,该组件基本上是一个表,其中包含代表某些用户的条目。
该组件经过设计,因此还有一个名为table-list的组件,它描述了一个表及其对多个组件的行为(user-table-list是其中之一)。 user-table-list的html实际上是这样的:

<app-table-list #table [tableConfiguration]="usersTableConfiguration"></app-table-list>

table-list的html具有表的所有设计,描述了列,标题等...,而单个组件在.ts文件中描述了其个人表的配置,这意味着它们将数据加载以填充表格,列名等等。
在标题中,有一个按钮可以向表中添加新条目,让它成为用户或客户或其他任何对象。事件和数据库检索在table-list.component.ts内部处理,根据事件来自哪种表类型执行不同的onclick操作。像这样:

createNewButtonClicked(tableType: string) {

    const dialogConfig = new MatDialogConfig();
    dialogConfig.width = '60%';
    dialogConfig.autoFocus = true;

    switch (tableType) {
        case 'clients': {
            this.dialog.open(ClientDialogComponent, dialogConfig);
            break;
        }
        case 'projects': {
            this.dialog.open(ProjectDialogComponent, dialogConfig);
            break;
        }  
        case 'users':{
            this.dialog.open(UserDialogComponent, dialogConfig);
            break;
        }
    }
}

在打开的对话框中,新的客户端/项目/用户将添加到列表中。我想要的是在关闭对话框后通过调用数据库检索方法来刷新列表。但是,这种检索在单个组件(例如user-table-list)内部被调用。因此,我正在寻找一种调用检索方法并从外部刷新user-table-list列表的方法,而不必从浏览器刷新页面。问题是我无法做到这一点,无论是在对话框组件还是在表列表组件中。我尝试过在对话框和表列表组件中导入构造函数中的组件并调用该方法,但是它为循环引用提供了警告,并且不执行任何操作。如果创建外部服务来调用该方法,则相同,因为总是有一个循环引用。
我没有其他选择了。该怎么办呢?
不幸的是,我无法更改应用程序设计。

2 个答案:

答案 0 :(得分:1)

假设您使用的是实质性对话框,则对话框为您提供了一个观察对象,您可以观察该对话框何时关闭。如果将其设置为变量,则可以在关闭时监视它,例如:

createNewButtonClicked(tableType: string) {
    // your existing logic
    // ... 
    const dialog = this.dialog.open(ClientDialogComponent, dialogConfig);
    // example dialog .afterClosed
    dialog.afterClosed().subscribe(closeResult => {
        // update from database after dialog is closed
    });
}

您可以使用Output属性来告诉父组件在孩子内部发生了某些事情。在subscribe函数(我在其中添加评论以更新数据库)的内部,您想发出该对话框已关闭的信息。您的清单程式码可能看起来像这样:     @Output()dialogClosed =新的EventEmitter();

createNewButtonClicked(tableType: string) {
    const dialogConfig = new MatDialogConfig();
    dialogConfig.width = '60%';
    dialogConfig.autoFocus = true;
    let dialog;
    switch (tableType) {
        case 'clients': {
            dialog = this.dialog.open(ClientDialogComponent, dialogConfig);
            break;
        }
        case 'projects': {
            dialog = this.dialog.open(ProjectDialogComponent, dialogConfig);
            break;
        }  
        case 'users':{
            dialog = this.dialog.open(UserDialogComponent, dialogConfig);
            break;
        }
    }
    // check to see if dialog was opened
    if (!!dialog) {
        dialog.afterClosed().subscribe(closeResult => {
            // emit that dialog was closed
            this.dialogClosed.next();
        });
    }
}

然后在用户表组件中监视要发出的事件:

<app-table-list (dialogClosed)="onDialogClosed($event)"></app-table-list>

最后,您的用户表ts。请注意,关闭对话框时我不会调用ngOnInit,因为ngOnInit的目的是初始化。因此,将ngOnInit内部的数据库逻辑提取到另一个方法中,并在对话框关闭时也调用此方法来更新数据:

ngOnInit() {
  this.getData();
}

onDialogClose() {
    this.getData();
}

private getData() {
  // make database calls here and update data from response
}

您只应使用ngOnInit初始化视图,因为您可能会在此处设置一些不想重置的默认值,因此建议不要在页面生命周期的稍后再调用ngOnInit

答案 1 :(得分:0)

必须从对话框内的“提交”按钮发出事件。也就是说,捕获对话框的click事件,并从表列表中通知单击的父组件。

类似的东西:

table-list.component.ts

@Output() clickedOkDialog = new EventEmitter<boolean>();

onClickOkDialog() {
  this.clickedOkDialog.emit(true);
}

然后您可以在用户表列表中捕获事件

在您的user-table-list.component.html

<app-table-list (clickedOkDialog)="onClickOkDialog($event)" #table [tableConfiguration]="usersTableConfiguration"></app-table-list>

在您的user-table-list.component.ts

onClickOkDialog(event) {
   // update from database after dialog is closed
}