【发布时间】:2019-11-22 22:37:39
【问题描述】:
我需要监听子组件触发的事件。就我而言,我有一个用模板 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,Angular 也看不到“clicktab”。
有什么提示吗?
【问题讨论】:
-
我怀疑你可以在 Angular 组件上使用 Stencil 的
@Listen装饰器...... Angular 的@Listen对应物是@Input。 -
另外,您的活动名称是
tabClick而不是clicktab。 -
@MichalCumpl 对!但结果相同:(
-
@SimonHänisch 但它是模板的组件,并且不是“输入”一个属性,用于将变量发送到角度组件之间的子组件而不是第三方库......?像模具?
-
那你能更新你的代码吗?您应该在 ts 文件中使用 @HostListener('tabClick') 或在 Angular 模板中使用 (tabClick)="handleTabClick()"。
标签: javascript angular stenciljs