【问题标题】:Angular - Access elementRef of MatMenuAngular - 访问 MatMenu 的 elementRef
【发布时间】:2021-07-22 14:30:39
【问题描述】:

我有以下设置:

@Directive({
    selector: '[test]'
})
export class Test {
    constructor(
        private hostRef: ElementRef,
        private host: MatMenuTrigger,
    ) {}

    ngOnInit() {
        this.host.menuOpened.subscribe(() => {
            /* Do something with the MatMenu elementRef */
        });
    }
}
<a [matMenuTriggerFor]="aMenu" test></a>
<mat-menu #aMenu></mat-menu>

我想获取 MatMenu 的 ElementRef(不是对打开的 MatMenu 组件的引用,也不是 MatMenuTrigger 的 elementRef)。 在查看了 MatMenu 类的 typescript 定义文件后,我发现了 _elementRef 私有属性,它允许我像这样访问 elementRef:

this.host.menuOpened.subscribe(() => {
    const ref = (this.host.menu as any)._elementRef;
    /* Do something with ref */
});

唯一的问题是,这依赖于 Angular 团队在未来的版本中维护这个属性(而且,事实上,这是一个私有属性开始的事实)。

我可以将test 指令直接放在mat-menu 模板上,这样我就可以使用ElementRef 注入器访问它的elementRef,但我会失去对openMenu 和@ 等MatMenuTrigger 函数的访问权限987654330@(MatMenu 实例不包含对其任何关联 MatMenuTrigger 的任何引用)。

有没有一种方法可以在不使用其私有属性的情况下访问 MatMenu 的 ElementRef(或者在不访问关联的 MatMenuTrigger 的情况下关闭 MatMenu 的方法)?
我需要 ElementRef 来测试对 document 的点击是否来自菜单(通过测试菜单 elementRef 是否包含在事件 composedPath 中)

【问题讨论】:

  • @ViewChild(MatMenu, {read: ElementRef}) 会为你工作吗?
  • 这不起作用,因为 MatMenu 不是 MatMenuTrigger 的子项。我可以在主机组件中使用它(就像在托管触发器和菜单模板的组件中一样),但我试图将所有内容都放在指令中(以便它可以被其他组件重用)。

标签: angular angular-material


【解决方案1】:

听起来您正在尝试将对 mat-menu 元素的引用传递给您的 test 指令。如果是这种情况,请尝试在指令中添加 Input()

@Input() menu: MatMenu;

然后在你的模板中:

<a [matMenuTriggerFor]="aMenu" test [menuRef]="aMenu"></a>
<mat-menu #aMenu></mat-menu>

这样,您可以通过本地引用将组件传递给您的指令。

【讨论】:

  • 虽然这确实允许我获得对 MatMenu 组件实例的引用,但这并不能解决我的问题:我正在寻找 MatMenu 的 ElementRef,而不是 MatMenu 本身(并且 @Input 不支持读取元数据属性,我无法以这种方式获取元素引用)
猜你喜欢
  • 2017-09-11
  • 2021-12-11
  • 2023-03-05
  • 1970-01-01
  • 1970-01-01
  • 2019-03-24
  • 2021-10-04
  • 1970-01-01
  • 2018-09-28
相关资源
最近更新 更多