Angular 角度5:如何从父组件HTML模板引用子组件方法?

Angular 角度5:如何从父组件HTML模板引用子组件方法?,angular,typescript,angular5,Angular,Typescript,Angular5,我有一个对话框子组件DeleteAssociationDialog,其中包含openDeleteAssociationDialog方法: 删除关联对话框.component.ts import { Component } from '@angular/core'; import { MatDialog, MatDialogRef } from '@angular/material'; @Component({ selector: 'app-delete-association-dialog

我有一个对话框子组件DeleteAssociationDialog,其中包含openDeleteAssociationDialog方法:

删除关联对话框.component.ts

import { Component } from '@angular/core';
import { MatDialog, MatDialogRef } from '@angular/material';

@Component({
  selector: 'app-delete-association-dialog',
  templateUrl: 'delete-association-dialog.component.html',
  styleUrls: ['delete-association-dialog.component.css']
})
export class DeleteAssociationDialogComponent {

  constructor(
  public dialog: MatDialog,
  public dialogRef: MatDialogRef<DeleteAssociationDialogComponent>) { }

  openDeleteAssociationDialog(): void {
    let dialogRef = this.dialog.open(DeleteAssociationDialogComponent, {
      width: '250px'
    });

    dialogRef.afterClosed().subscribe(result => {
      console.log('The dialog was closed');
    });
  }
}
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatButtonModule } from '@angular/material/button';
import { MatInputModule } from '@angular/material';
import { FormsModule } from '@angular/forms';
import { MatDialogModule } from '@angular/material';

import { AppComponent } from './app.component';
import { DeleteAssociationDialogComponent } from './delete-association-dialog/delete-association-dialog.component';

import { MatDialogRef} from '@angular/material/dialog'

@NgModule({
  declarations: [
    AppComponent,
    DeleteAssociationDialogComponent,
  ],
  entryComponents: [DeleteAssociationDialogComponent],
  imports: [
    BrowserModule,
    NgModule,
    BrowserAnimationsModule,
    MatButtonModule,
    MatInputModule,
    FormsModule
    MatDialogModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
import { Component, ViewChild } from '@angular/core';
import { MatDialog, MatDialogRef } from '@angular/material';
import { DeleteAssociationDialogComponent } from './delete-association-dialog/delete-association-dialog.component';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css', './app.component.panel.css']
})
export class AppComponent {
  @ViewChild('DeleteAssociationDialogComponent') child: DeleteAssociationDialogComponent;
}
@Component({
  selector: 'association-deleter',
  template: `<button (click)="openDialog()"></button>`
})
export class DeleteAssociationComponent {
  constructor(
    public dialog: MatDialog,
    public dialogRef: MatDialogRef<DeleteAssociationDialogComponent>
  ){}

  openDeleteAssociationDialog(): void {
    let dialogRef = this.dialog.open(DeleteAssociationDialogComponent, {
      width: '250px'
    });

    dialogRef.afterClosed().subscribe(result => {
      console.log('The dialog was closed');
    });
  }
}
应用程序组件.ts

import { Component } from '@angular/core';
import { MatDialog, MatDialogRef } from '@angular/material';

@Component({
  selector: 'app-delete-association-dialog',
  templateUrl: 'delete-association-dialog.component.html',
  styleUrls: ['delete-association-dialog.component.css']
})
export class DeleteAssociationDialogComponent {

  constructor(
  public dialog: MatDialog,
  public dialogRef: MatDialogRef<DeleteAssociationDialogComponent>) { }

  openDeleteAssociationDialog(): void {
    let dialogRef = this.dialog.open(DeleteAssociationDialogComponent, {
      width: '250px'
    });

    dialogRef.afterClosed().subscribe(result => {
      console.log('The dialog was closed');
    });
  }
}
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatButtonModule } from '@angular/material/button';
import { MatInputModule } from '@angular/material';
import { FormsModule } from '@angular/forms';
import { MatDialogModule } from '@angular/material';

import { AppComponent } from './app.component';
import { DeleteAssociationDialogComponent } from './delete-association-dialog/delete-association-dialog.component';

import { MatDialogRef} from '@angular/material/dialog'

@NgModule({
  declarations: [
    AppComponent,
    DeleteAssociationDialogComponent,
  ],
  entryComponents: [DeleteAssociationDialogComponent],
  imports: [
    BrowserModule,
    NgModule,
    BrowserAnimationsModule,
    MatButtonModule,
    MatInputModule,
    FormsModule
    MatDialogModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
import { Component, ViewChild } from '@angular/core';
import { MatDialog, MatDialogRef } from '@angular/material';
import { DeleteAssociationDialogComponent } from './delete-association-dialog/delete-association-dialog.component';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css', './app.component.panel.css']
})
export class AppComponent {
  @ViewChild('DeleteAssociationDialogComponent') child: DeleteAssociationDialogComponent;
}
@Component({
  selector: 'association-deleter',
  template: `<button (click)="openDialog()"></button>`
})
export class DeleteAssociationComponent {
  constructor(
    public dialog: MatDialog,
    public dialogRef: MatDialogRef<DeleteAssociationDialogComponent>
  ){}

  openDeleteAssociationDialog(): void {
    let dialogRef = this.dialog.open(DeleteAssociationDialogComponent, {
      width: '250px'
    });

    dialogRef.afterClosed().subscribe(result => {
      console.log('The dialog was closed');
    });
  }
}
出错-- “错误类型错误:无法读取未定义的属性“openDeleteAssociationDialog”


我错过了什么?如何正确引用父组件HTML模板中的子组件方法?

我认为问题源于打开对话框的方法包含在对话框本身中这一事实。因此,除非对话框已经打开,否则该方法将不存在……对话框组件是鸡和蛋

解决方案是将方法移动到父对象的
openDeleteAssociationDialogComponent

然后很简单:

<button (click)="openDeleteAssociationDialogComponent()"></button>

如果要将其抽象出来以使对话框打开按钮可重复使用,可以执行以下操作:

component.html

<association-deleter></association-deleter>

组件。ts

import { Component } from '@angular/core';
import { MatDialog, MatDialogRef } from '@angular/material';

@Component({
  selector: 'app-delete-association-dialog',
  templateUrl: 'delete-association-dialog.component.html',
  styleUrls: ['delete-association-dialog.component.css']
})
export class DeleteAssociationDialogComponent {

  constructor(
  public dialog: MatDialog,
  public dialogRef: MatDialogRef<DeleteAssociationDialogComponent>) { }

  openDeleteAssociationDialog(): void {
    let dialogRef = this.dialog.open(DeleteAssociationDialogComponent, {
      width: '250px'
    });

    dialogRef.afterClosed().subscribe(result => {
      console.log('The dialog was closed');
    });
  }
}
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatButtonModule } from '@angular/material/button';
import { MatInputModule } from '@angular/material';
import { FormsModule } from '@angular/forms';
import { MatDialogModule } from '@angular/material';

import { AppComponent } from './app.component';
import { DeleteAssociationDialogComponent } from './delete-association-dialog/delete-association-dialog.component';

import { MatDialogRef} from '@angular/material/dialog'

@NgModule({
  declarations: [
    AppComponent,
    DeleteAssociationDialogComponent,
  ],
  entryComponents: [DeleteAssociationDialogComponent],
  imports: [
    BrowserModule,
    NgModule,
    BrowserAnimationsModule,
    MatButtonModule,
    MatInputModule,
    FormsModule
    MatDialogModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
import { Component, ViewChild } from '@angular/core';
import { MatDialog, MatDialogRef } from '@angular/material';
import { DeleteAssociationDialogComponent } from './delete-association-dialog/delete-association-dialog.component';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css', './app.component.panel.css']
})
export class AppComponent {
  @ViewChild('DeleteAssociationDialogComponent') child: DeleteAssociationDialogComponent;
}
@Component({
  selector: 'association-deleter',
  template: `<button (click)="openDialog()"></button>`
})
export class DeleteAssociationComponent {
  constructor(
    public dialog: MatDialog,
    public dialogRef: MatDialogRef<DeleteAssociationDialogComponent>
  ){}

  openDeleteAssociationDialog(): void {
    let dialogRef = this.dialog.open(DeleteAssociationDialogComponent, {
      width: '250px'
    });

    dialogRef.afterClosed().subscribe(result => {
      console.log('The dialog was closed');
    });
  }
}
@组件({
选择器:'关联删除器',
模板:``
})
导出类DeleteAssociationComponent{
建造师(
公共对话:MatDialog,
公共dialogRef:MatDialogRef
){}
openDeleteAssociationDialog():void{
让dialogRef=this.dialog.open(DeleteAssociationDialogComponent{
宽度:'250px'
});
dialogRef.afterClosed().subscribe(结果=>{
log(“对话框已关闭”);
});
}
}

然后,您可以重复使用打开“删除关联”对话框的按钮。

为什么要这样做?这听起来像是糟糕的做法请添加你的
/app.component.html
code这个想法是为了划分对话框组件,因为我真的不想在app.component.ts中有多个@component。我是Angular的新手,所以还不太熟悉它的最佳实践,但在单个app.Component.ts中为每个对话框使用多个@Component显然是一个糟糕的实践:)@OvidiuDolha在方法所在的位置添加了它的片段called@porgo我试过了,得到了“NullInjectorError:MatDialogRef没有提供程序!”,我还读到对话框不需要它。我正在处理的问题是,我无法从父组件HTML引用子组件方法,也无法在父组件HTML中引用子组件选择器。看起来我正在以非惯用的方式做一些事情,但我无法想象一个单一的主组件的体系结构,其中包含从父组件HTML到子组件中的方法的点击引用,这是不寻常的。。人们是否只是将所有对话框代码合并到一个组件中?您可以引用子组件方法,假设该方法是公共的,并且子组件已定义。但是,您当前正在尝试调用对话框上的方法,该对话框在打开之前不存在。请参阅我的更新答案,为您选择的两个选项。很高兴我能帮助-考虑上投票表明它是有益的和/或标记为接受,所以其他人知道你的问题得到了答复。欢迎来到SO:)