首页 > 解决方案 > 从模板中获取元素兄弟组件 ng-content

问题描述

我正在尝试制作一个有角度的弹出框。目前有两个组件和一个指令。

当我点击我的按钮时,我收到一条错误消息

错误类型错误:无法读取未定义的属性“openPopover”

如何从指令中获取对父级的引用,然后从该父级获取子级?

因此,点击路径如下所示:[open-popover] / <map-popover> / <map-popover-content>

app.component.html

<mat-popover>
  <mat-popover-content>
    <p>Hello World</p>
  </mat-popover-content>
  <button mat-flat-button open-popover color="primary">Add Debt</button>
</mat-popover>

popover.component.ts

@Component({
  selector: 'mat-popover',
  template: '<ng-content></ng-content>',
  styleUrls: ['./popover.component.scss']
})
export class MatPopoverComponent {

  @ViewChild(MatPopoverContentComponent)
  public content: MatPopoverContentComponent

  public open() {
    this.content.openPopover()
  }
}

内容.component.ts

@Component({
  selector: 'mat-popover-content',
  template: `<ng-template #popoverContent>
    <ng-content></ng-content>
  </ng-template>`,
  styleUrls: ['./content.component.scss']
})
export class MatPopoverContentComponent {

  @ViewChild('popoverContent')
  public template: TemplateRef<any>

  public constructor(public dialog: MatDialog) { }

  openPopover(): void {
    this.dialog.open(this.template, {
      hasBackdrop: false
    })
  }
}

open.directive.ts

@Directive({
  selector: '[open-popover]'
})
export class OpenPopoverDirective {

  public constructor(@Host() private popover: MatPopoverComponent) { }

  @HostListener('click')
  public onClick() {
    this.popover.open()
  }
}

标签: javascriptangulartypescript

解决方案


用这里替换ContentChild装饰器,它应该可以工作。ViewChild@ViewChild(MatPopoverContentComponent)

解释

您应该区分 Light DOM 和 Shadow DOM:

零件

@Component({
  selector: 'mat-popover',
  template: `<ng-content></ng-content>`, <--- Shadow DOM
  styleUrls: ['./popover.component.scss']
})
export class MatPopoverComponent {}

消费者

<mat-popover>
  <!-- Light DOM starts -->
  <mat-popover-content>
    <p>Hello World</p>
  </mat-popover-content>
  <button mat-flat-button open-popover color="primary">Add Debt</button>
  <!-- Light DOM ends-->
</mat-popover>

所以在 Angular 中,我们使用 ViewChild/ren 查询 Shadow DOM 中的元素,使用 ContentChild/ren 查询 Light DOM 中的元素


推荐阅读