如何在sc-drawer组件中通过drawer-track指令获取sc-list宿主元素
解决方案
这里有几种可行的方法来在sc-drawer组件中获取sc-list的宿主元素,具体如下:
方法1:通过输入的组件实例直接获取宿主元素
因为你在模板中通过[drawerTrack]="list"传递的是sc-list组件的实例,所以可以在sc-drawer中通过该实例的ElementRef拿到宿主元素,前提是sc-list组件公开了自己的ElementRef:
步骤1:在sc-list组件中暴露ElementRef
// sc-list.component.ts import { Component, ElementRef } from '@angular/core'; @Component({ selector: 'sc-list', templateUrl: './sc-list.component.html' }) export class ScListComponent { // 公开ElementRef,让其他组件可以访问 constructor(public elementRef: ElementRef) {} }
步骤2:在sc-drawer组件中获取宿主元素
// sc-drawer.component.ts import { Component, Input, OnInit } from '@angular/core'; import { ScListComponent } from './sc-list.component'; @Component({ selector: 'sc-drawer', templateUrl: './sc-drawer.component.html' }) export class ScDrawerComponent implements OnInit { @Input() drawerTrack: ScListComponent; ngOnInit(): void { // 获取sc-list的宿主DOM元素 const listHostElement = this.drawerTrack.elementRef.nativeElement; // 这里可以对元素进行后续操作,比如监听滚动、获取尺寸等 } }
方法2:通过drawer-track指令提供可注入的元素引用
如果drawer-track是你自定义的指令,可以让它直接提供宿主元素的引用,方便在sc-drawer中获取:
步骤1:定义注入令牌
// drawer-track.tokens.ts import { InjectionToken } from '@angular/core'; export const DRAWER_TRACK_HOST_ELEMENT = new InjectionToken<HTMLElement>( 'Host element of the component with drawer-track directive' );
步骤2:修改drawer-track指令
// drawer-track.directive.ts import { Directive, ElementRef, Provider } from '@angular/core'; import { DRAWER_TRACK_HOST_ELEMENT } from './drawer-track.tokens'; @Directive({ selector: '[drawer-track]', providers: [ { provide: DRAWER_TRACK_HOST_ELEMENT, useFactory: (dir: DrawerTrackDirective) => dir.elementRef.nativeElement, deps: [DrawerTrackDirective] } ] }) export class DrawerTrackDirective { constructor(public elementRef: ElementRef) {} }
步骤3:传递指令实例到sc-drawer
修改模板,把drawer-track指令的实例传递给sc-drawer:
<sc-list #list drawer-track></sc-list> <sc-drawer [drawerTrackDir]="list.drawerTrack"></sc-drawer>
(注:需要在sc-list组件中通过@ViewChild(DrawerTrackDirective)获取指令实例,并公开为drawerTrack属性)
然后在sc-drawer中直接获取元素:
// sc-drawer.component.ts import { Component, Input, OnInit } from '@angular/core'; import { DrawerTrackDirective } from './drawer-track.directive'; @Component({ selector: 'sc-drawer', templateUrl: './sc-drawer.component.html' }) export class ScDrawerComponent implements OnInit { @Input() drawerTrackDir: DrawerTrackDirective; ngOnInit(): void { const listHostElement = this.drawerTrackDir.elementRef.nativeElement; // 进行后续操作 } }
方法3:直接传递宿主元素到sc-drawer
如果不想依赖组件实例或指令,也可以直接在模板中把sc-list的宿主元素传递给sc-drawer:
修改模板
<sc-list #list drawer-track></sc-list> <sc-drawer [drawerTrackElement]="list.elementRef.nativeElement"></sc-drawer>
在sc-drawer中接收元素
// sc-drawer.component.ts import { Component, Input, OnInit } from '@angular/core'; @Component({ selector: 'sc-drawer', templateUrl: './sc-drawer.component.html' }) export class ScDrawerComponent implements OnInit { @Input() drawerTrackElement: HTMLElement; ngOnInit(): void { // 直接使用this.drawerTrackElement } }
内容的提问来源于stack exchange,提问作者Yassine Klilich
相关产品推荐
相关产品推荐

