设置@HostDirective()后,如何获取动态组件中指令的事件?
如何在使用@HostDirective()时获取动态组件中指令的事件
一、在DynamicComponent内部获取HostDirective的事件
通过依赖注入结合@Self()装饰器,可以直接获取附加到组件宿主的OneDirective实例,进而订阅其事件:
import { Component, Input, Output, EventEmitter, Self, OnInit } from '@angular/core'; import { OneDirective } from './one.directive'; @Component({ selector: 'app-dynamic', template: `{{ message }}`, standalone: true, hostDirectives: [ { directive: OneDirective, outputs: ['change: messageChange'], }, ], }) export class DynamicComponent implements OnInit { @Input() message: string; @Output() messageChange = new EventEmitter(); constructor(@Self() private oneDirective: OneDirective) {} ngOnInit() { // 订阅指令的change事件 this.oneDirective.change.subscribe((value) => { console.log('DynamicComponent内部收到指令事件:', value); // 若无需hostDirectives的自动转发,可手动将事件转发到messageChange // this.messageChange.emit(value); }); } }
二、在动态创建组件的外部(OneComponent)获取事件
当前配置中,hostDirectives已将OneDirective的change事件自动转发到DynamicComponent的messageChange输出,因此直接订阅组件实例的messageChange即可:
import { Component, AfterViewInit, ViewChild, ViewContainerRef, ChangeDetectorRef } from '@angular/core'; import { DynamicComponent } from './dynamic.component'; @Component({ selector: 'app-one', template: `<ng-template #container></ng-template>`, standalone: true, }) export class OneComponent implements AfterViewInit { @ViewChild('container', { read: ViewContainerRef }) container: ViewContainerRef; constructor(private cdr: ChangeDetectorRef) {} ngAfterViewInit(): void { const component = this.container.createComponent(DynamicComponent); component.setInput('message', 'help me'); // 订阅组件的messageChange输出 component.instance.messageChange.subscribe((x) => { console.log('OneComponent收到事件:', x); }); this.cdr.detectChanges(); } }
关键注意事项
hostDirectives的outputs配置会自动将指令的事件转发到组件的对应输出属性,无需手动编写转发逻辑;- 若不需要自动转发,可移除
outputs配置,通过注入指令实例手动处理事件; - 动态创建组件时,
ComponentRef.instance可直接访问组件的输入输出,确保订阅操作在组件初始化前完成,避免错过事件触发; - 修正
OneDirective的选择器拼写错误(原代码为one-driective,建议改为one-directive),避免后续使用指令选择器时出现问题。
内容的提问来源于stack exchange,提问作者ajie
相关产品推荐
相关产品推荐

