javascript - 从 StencilJS 到 Angular 的事件发射器
问题描述
我需要监听子组件触发的事件。就我而言,我有一个用模板 v1 制作的“标签”组件,它具有这种结构......
abc-tabs.tsx
import { Component, h, Listen, Element, State, Event, Method, EventEmitter } from '@stencil/core';
@Component({
tag: 'abc-tabs'
})
export class AepTabs {
@Element() tabs: HTMLElement;
@State() initIndex: number = 0;
@Event() tabClick: EventEmitter; // <---------- HERE
private tabsElements;
private tabsElementList: Array<any> = [];
private tabTitleElements: any;
componentWillLoad() {
this.createTabsTitles(this.tabs.querySelectorAll('abc-tab'));
}
componentDidLoad() {
this.addTitleEvents();
}
addTitleEvents() {
this.tabTitleElements = this.tabs.getElementsByClassName('tab-title');
[].forEach.call(this.tabTitleElements, (tab, pos) => {
tab.addEventListener('click', () => {
this.tabClick.emit(tab);
this.activeTabs(pos);
});
});
this.activeTabs(this.initIndex);
}
createTabsTitles(tabsList: NodeList) {
this.tabsElements = tabsList;
[].forEach.call(this.tabsElements, tab => {
this.tabsElementList.push(
<div class="tab-title" data-automation={tab.titletab.toString().toLowerCase()}>
<span>{tab.titletab}</span>
</div>
);
});
}
@Method()
activeTabs(index: number) {
this.tabTitleElements = this.tabs.getElementsByClassName('tab-title');
[].forEach.call(this.tabTitleElements, (tab, pos) => {
if (index === pos) {
tab.classList.add('active');
tab.classList.remove('inactive');
} else {
tab.classList.remove('active');
tab.classList.add('inactive');
}
});
[].forEach.call(this.tabsElements, (tab, pos) => {
if (index === pos) {
tab.classList.add('active');
tab.classList.remove('inactive');
} else {
tab.classList.remove('active');
tab.classList.add('inactive');
}
});
}
// HERE --------------------------------------------------------
@Listen('tabClick')
clicktabHandler(event: CustomEvent) {
this.activeTabs(event.detail);
}
// HERE --------------------------------------------------------
render() {
return (
<div>
<nav>{this.tabsElementList}</nav>
<div>
<div>
<slot />
</div>
</div>
</div>
);
}
}
因此,在我的 Angular 项目中,我使用了模板组件。
detail.component.html
<abc-tabs>
<abc-tab titletab="My first tab">
<!-- content here -->
</abc-tab>
<abc-tab titletab="My second tab" >
<!-- content here -->
</abc-tab>
</abc-tabs>
一切都很完美,但现在我需要@Listen(在 Angular 中)单击某些选项卡时触发的事件,所以我在 detail.component.ts 类中执行此操作:
detail.component.ts
import { Component, OnInit } from '@angular/core';
import { Listen, Watch } from '@stencil/core';
@Component({
selector: 'app-detail',
templateUrl: './detail.component.html'
})
export class DetailComponent implements OnInit {
constructor() {}
ngOnInit() {}
@Listen('tabClick') // <--- ERROR HERE
clicktabHandler(event: CustomEvent) {
console.log('has clicked!!!! ', event.detail);
}
}
但是,它会在detail.component.ts中引发错误:
ERROR Error: Uncaught (in promise): TypeError: Object(...) is not a function
TypeError: Object(...) is not a function
即使我从@stencil/core 导入@Listen,似乎“clicktab”也是 Angular 看不到的。
有什么提示吗?
解决方案
您应该使用@HostListener('tabClick')
而不是@Listen('tabClick')
.
推荐阅读
- java - 如何使用python自动退出jdb
- android - 网络实用程序类的单元测试
- python - 如何在水平条形图中添加百分比?
- html - 如何解决 WordPress 中的传入电子邮件错误
- c - 找到以下程序复杂性的严格上限:
- python - 为什么我的日期时间对象被转换为 Unicode
- vb.net - Visual Studio 中 datetimepicker 中的默认日期
- java - enum - 不能从非静态上下文中引用非静态方法
- java - 当凭据存储在主数据库中时,使用本地数据库在本地应用程序上对用户进行身份验证
- sql - 给定一个经度/纬度,将米转换为经度/纬度